Skip to content

Conversation

@PythonTilk
Copy link
Owner

No description provided.

BenediktBurger and others added 6 commits August 8, 2025 10:11
This commit introduces two new files:

- LINUX_AUDIO.md: Documents the current state of audio support on Linux.
- LINUX_SUPPORT.md: Provides a comprehensive overview of missing features for full Linux support.
@coderabbitai
Copy link

coderabbitai bot commented Nov 10, 2025

Note

Other AI code review bot(s) detected

CodeRabbit has detected other AI code review bot(s) in this pull request and will avoid duplicating their findings in the review comments. This may lead to a less comprehensive review.

📝 Walkthrough

Walkthrough

Adds broad Linux support and related features: PulseAudio/ALSA speaker capture, mic discovery and calibration, desktop notifications (D‑Bus), XDG autostart, Linux detectors (apps/browsers/mic), CalDAV/CardDAV calendar & contacts with credential vault, listener speaker APIs, DB migrations, JS bindings, examples, and Linux packaging CI.

Changes

Cohort / File(s) Summary
Docs & Roadmap
LinuxInstallNotes.md, linuxtodo.md, .github/workflows/README_linux_packages.md, WORKFLOW_REVIEW.md, CLAUDE.md
New Linux install notes, TODO/status roadmap, packaging workflow docs, workflow review, and agent guidance.
Audio core & backends
crates/audio/Cargo.toml, crates/audio/src/lib.rs, crates/audio/src/errors.rs, crates/audio/src/mic.rs, crates/audio/src/speaker/*, crates/audio/src/bin/*
Add DeviceKind/DeviceInfo, device listing/default helpers, availability checks, PulseAudio/ALSA backend detection & capture, Result-based constructors/stream APIs, expanded Error enum, tracing, and new test/example binaries.
Detect crate (Linux observers)
crates/detect/Cargo.toml, crates/detect/src/app/linux.rs, crates/detect/src/browser/linux.rs, crates/detect/src/mic/linux.rs, crates/detect/src/{app,browser,mic}/mod.rs
New Linux observers for apps, browsers, and microphone-in-use using ps/pactl; tokio macros enabled.
Notifications (Linux)
crates/notification2/Cargo.toml, crates/notification2/src/lib.rs, crates/notification2/src/linux.rs
New Linux notification module: desktop-environment detection, open-settings helpers, D‑Bus daemon checks, permission-check callbacks, and request/open settings helpers.
Calendar & contacts (CalDAV/CardDAV + macOS bridge)
crates/calendar-apple/Cargo.toml, crates/calendar-apple/src/{caldav.rs,carddav_client.rs,macos_native.rs,lib.rs}, crates/calendar-apple/README.md, plugins/apple-calendar/*
Add CalDavHandle/CardDavHandle (PROPFIND/REPORT, ICAL parsing), macOS EventKit bridge, contact sync, credential commands, and Linux credential injection via tauri-plugin-auth.
Calendar interface
crates/calendar-interface/src/lib.rs
Added ContactSource trait and Contact struct.
Database: audio & contacts
crates/db-user/src/{config_types.rs,config_ops.rs,init.rs,lib.rs}, crates/db-user/src/{configs_migration_1.sql,contacts_migration.sql}, crates/db-user/src/{contacts_*,contacts_types.rs}
Added ConfigAudio and audio field to Config, SQL migrations adding audio and contacts table, contacts types/ops and public exports.
Listener plugin: commands, FSM, events, JS bindings
plugins/listener/Cargo.toml, plugins/listener/src/{ext.rs,fsm.rs,commands.rs,events.rs,error.rs,lib.rs}, plugins/listener/js/bindings.gen.ts
Added speaker APIs (list/get/set/default), DeviceInfo usage, audio gains, mic test start/stop/status, automatic calibration workflow/events (CalibrationProgressEvent/CalibrationResult), FSM speaker state, permission files and updated JS bindings/types.
Listener permissions
plugins/listener/permissions/*
Added autogenerated permission TOML files and expanded schema/defaults for mic-test, calibration, speaker management, and audio gains.
Connector plugin: feature gating
plugins/connector/Cargo.toml, plugins/connector/src/{error.rs,ext.rs}, apps/desktop/src-tauri/Cargo.toml
Make local-llm/local-stt optional features; feature-gate error variants and connection logic; desktop enables those features.
Auth vault extensions
plugins/auth/src/vault.rs, plugins/auth/js/bindings.gen.ts
Added CalDAV/CardDAV credential keys and VaultData fields; JS bindings extended.
Apple Calendar plugin: commands & sync
plugins/apple-calendar/src/{commands.rs,ext.rs,lib.rs,sync.rs}, plugins/apple-calendar/js/bindings.gen.ts, plugins/apple-calendar/Cargo.toml
Add CalDavCredentials type, credential set/get/test/clear commands, sync_contacts and contact sync flow, Linux credential injection and auth plugin usage.
Desktop app: Linux init & Sentry
apps/desktop/src-tauri/src/lib.rs, apps/desktop/src-tauri/Cargo.toml
Set XDG_RUNTIME_DIR/DBUS inference on Linux, conditional Sentry init, removed enforced autostart-disable, enabled connector features.
Desktop UI: sound, settings, calendar UI
apps/desktop/src/components/settings/views/{sound.tsx,general.tsx}, apps/desktop/src/components/settings/components/calendar/icloud-credentials-modal.tsx, apps/desktop/src/components/settings/views/calendar/*, apps/desktop/src/components/welcome-modal/*
Microphone sensitivity slider, mic-test UI/events, automatic calibration UI/progress, autostart toggle, iCloud credentials modal and non-macOS credentials flow.
UI: device selection & contacts
apps/desktop/src/components/editor-area/...listen-button.tsx, apps/desktop/src/components/finder/views/contact-view.tsx, apps/desktop/src/components/right-panel/hooks/useTranscript.ts
Device lists use DeviceInfo with availability flags; selection flows updated; contact sync and local type rename Word→Word2 handled.
Translations & locales
apps/desktop/src/locales/*
Added/updated strings for iCloud credentials, mic test/calibration, audio settings, autostart, and related UI text.
Packaging & CI: Linux workflows
.github/workflows/{linux_packages.yaml,linux_packages_rpm.yaml,linux_packages_arch.yaml}, .github/workflows/README_linux_packages.md
New GitHub Actions for DEB/AppImage/RPM/Arch packaging with cross-compilation, verification and artifact publishing; docs added.
Examples & tests
crates/whisper-local/examples/*, crates/transcribe-whisper-local/examples/*, crates/file/examples/*, crates/audio/src/bin/*
Added examples and binaries for whisper backends, model checks, file checksum, and audio device listing/capture tests.
Misc & small fixes
.gitignore, owhisper/owhisper-server/src/{commands/run.rs,misc.rs}, plugins/windows/src/ext.rs, crates/notification2/Cargo.toml
.gitignore tweaks, server handle_run() returns Result and early-return dry-run, PoisonError guards/logging, Windows monitor fallback logs, added tracing dep for notification crate.

Sequence Diagram(s)

sequenceDiagram
    rect rgba(220,240,255,0.25)
    participant UI as Desktop UI
    participant JS as JS Bindings
    participant Plugin as Listener Plugin
    participant Audio as hypr_audio
    participant DB as User DB
    participant Events as Event Bus
    end

    UI->>JS: invoke calibrateMicrophone()
    JS->>Plugin: tauri invoke calibrate_microphone
    Plugin->>Audio: AudioInput::from_mic(None)
    Audio-->>Plugin: AudioInput or Err
    alt stream available
        loop per gain step
            Plugin->>Audio: consume samples
            Audio-->>Plugin: samples
            Plugin->>Plugin: transcribe & score
            Plugin->>Events: emit CalibrationProgressEvent
            Events-->>UI: progress update
        end
        Plugin->>DB: persist chosen ConfigAudio
        Plugin-->>UI: return CalibrationResult
    else error
        Plugin-->>UI: return error
    end
Loading
sequenceDiagram
    participant UI as Desktop UI
    participant JS as JS Bindings
    participant Plugin as Listener Plugin
    participant Audio as hypr_audio
    participant FSM as Session FSM

    UI->>JS: listSpeakerDevices()
    JS->>Plugin: invoke list_speaker_devices
    Plugin->>Audio: AudioInput::list_speaker_devices_info()
    Audio-->>Plugin: Vec<DeviceInfo>
    Plugin-->>UI: device list
    UI->>JS: setSpeakerDevice(name)
    JS->>Plugin: invoke set_speaker_device
    Plugin->>FSM: emit SpeakerChange(name)
    FSM-->>Plugin: acknowledge
    Plugin-->>UI: event speakerDeviceChanged
Loading

Estimated code review effort

🎯 5 (Critical) | ⏱️ ~120 minutes

Areas needing extra attention:

  • crates/audio: backend detection, capture threads, sample conversion, new Result APIs and expanded Error enum (crates/audio/src/speaker/linux.rs, crates/audio/src/mic.rs, crates/audio/src/lib.rs, crates/audio/src/errors.rs).
  • CalDAV/CardDAV and macOS EventKit bridge: HTTP PROPFIND/REPORT, ICAL parsing, credential handling and injection (crates/calendar-apple/src/{caldav.rs,carddav_client.rs,macos_native.rs}, plugins/apple-calendar/src/*).
  • Listener plugin: calibration/mic-test concurrency, streaming and event emission, FSM transitions, JS bindings and permissions schema updates (plugins/listener/src/commands.rs, plugins/listener/src/fsm.rs, plugins/listener/src/events.rs, plugins/listener/js/bindings.gen.ts).
  • Database migrations and schema changes for audio and contacts (crates/db-user/*, SQL migration files).
  • CI workflows and packaging scripts: cross-arch build logic, signing steps, environment/secrets handling (.github/workflows/linux_packages*.yaml).
  • Security-sensitive areas: credential storage/injection (plugins/auth, plugins/apple-calendar), D‑Bus interactions and permission checks (crates/notification2), and OS command invocations used by detectors/probes (ps, pactl).

Pre-merge checks and finishing touches

❌ Failed checks (2 inconclusive)
Check name Status Explanation Resolution
Title check ❓ Inconclusive The title 'Linux development' is vague and generic. While it relates to the changeset's Linux focus, it fails to clearly communicate the specific primary changes being introduced. Provide a more descriptive title that highlights the main features being added (e.g., 'Add production-ready Linux support with audio capture and notification system').
Description check ❓ Inconclusive No pull request description was provided by the author, making it impossible to assess relevance to the changeset. Add a detailed description explaining the major changes, implementation details, and any testing performed for this comprehensive Linux support addition.
✅ Passed checks (1 passed)
Check name Status Explanation
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch linux-development

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai
Copy link

coderabbitai bot commented Nov 10, 2025

Note

Docstrings generation - SUCCESS
Generated docstrings for this pull request at #2

Docstrings generation was requested by @PythonTilk.

* #1 (comment)

The following files were modified:

* `crates/audio/src/bin/test_mic.rs`
* `crates/audio/src/bin/test_speaker.rs`
* `crates/audio/src/lib.rs`
* `crates/audio/src/mic.rs`
* `crates/audio/src/speaker/linux.rs`
* `crates/audio/src/speaker/mod.rs`
* `crates/detect/src/app/linux.rs`
* `crates/detect/src/browser/linux.rs`
* `crates/detect/src/mic/linux.rs`
* `crates/file/examples/checksum.rs`
* `crates/transcribe-whisper-local/examples/show_data_dir.rs`
* `crates/whisper-local/examples/list_backends.rs`
* `crates/whisper-local/examples/test_model.rs`
* `crates/whisper-local/src/model.rs`
* `owhisper/owhisper-server/src/commands/run.rs`
* `plugins/listener/src/error.rs`
* `plugins/listener/src/ext.rs`
* `plugins/listener/src/fsm.rs`
📝 Add docstrings to `linux-development`
coderabbitai[bot]

This comment was marked as duplicate.

This comment was marked as duplicate.

coderabbitai[bot]

This comment was marked as duplicate.

…ures; clean speaker cfg gating and linux impl typo; doc trims
…serialize, clean mic builder docs, silence unused variable, ignore local wav artifact
…ements

- Replace unwrap/expect with proper Result types throughout audio crates
- Add mutex poison error handling in speaker/windows.rs
- Extract helper functions in mic.rs to eliminate code duplication:
  * create_standard_config() for unified configuration
  * validate_device_with_fallback() for device validation
  * try_build_test_stream() for sample format testing
- Improve browser detection error handling in detect/browser/linux.rs
- Add graceful regex compilation fallbacks in detect/browser/mod.rs
- Expand error types in audio/errors.rs for better error reporting
- Update plugin systems (listener, connector) for consistency
- Clean up documentation and remove verbose comments

Resolves 100+ potential panic points and significantly improves system robustness.
Maintains existing functionality while adding comprehensive error handling.
- Remove local-llm and local-stt from default features in connector plugin
- Makes heavy ML dependencies opt-in only to avoid forcing consumers to pull large deps
- Follows AGENTS.md guidelines for optional feature management

Addresses CodeRabbit feedback on feature configuration.
- Add section about comprehensive error handling improvements in LINUX_AUDIO.md
- Document audio system robustness and detection system improvements in LINUX_SUPPORT.md
- Update LinuxInstallNotes.md with information about recent updates and optional ML features
- Reflect elimination of 100+ panic points and improved device management
- Document graceful error handling in browser detection and system integration

Updates documentation to reflect the comprehensive CodeRabbit fixes completed.
BREAKING: Resolves the most critical missing Linux feature

• Add PulseAudio-based system audio capture in speaker/linux.rs
• Replace mock implementation with real audio capture from monitor sources
• Add libpulse-binding and libpulse-simple-binding dependencies
• Implement automatic audio backend detection (PulseAudio -> ALSA -> Mock)
• Add comprehensive error handling for audio system failures
• Include monitor source discovery using pactl commands
• Support 48kHz stereo capture with stereo-to-mono downmixing
• Add AudioSystem error variant for better error reporting
• Include extended test binary for real audio capture validation

Key improvements:
- Eliminates the primary Linux support gap (speaker audio capture)
- Provides foundation for full audio processing pipeline on Linux
- Maintains fallback compatibility with existing ALSA/mock implementations
- Uses feature flags to make PulseAudio optional ('pulseaudio' feature)

Tested successfully: Captures audio samples from PulseAudio monitor sources,
enabling Echo Cancellation and full transcription pipeline on Linux.
…plementation

🎉 Major milestone: Speaker audio capture fully implemented!

• Update LINUX_AUDIO.md to show PulseAudio implementation details
• Mark speaker capture as IMPLEMENTED in LINUX_SUPPORT.md
• Update priorities to reflect resolved critical blocker
• Add PulseAudio development library requirements to LinuxInstallNotes.md
• Highlight that core audio functionality is now complete on Linux
• Update Linux support status from 'missing critical feature' to 'production ready'

The primary blocker for Linux support has been eliminated. Full audio pipeline
including microphone capture, speaker capture, and Echo Cancellation is now
functional on Linux systems with PulseAudio.
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
crates/audio/src/mic.rs (1)

185-190: Avoid panicking when device enumeration fails.

Line 186 unwraps host.input_devices(); on Linux this call legitimately returns Err (e.g., when ALSA/PulseAudio isn’t available), so list_devices() will panic instead of behaving gracefully. Please propagate the error or return an empty list/log, similar to the other enumeration helpers.

Apply this diff to remove the panic while preserving the existing fallback string:

-        cpal::default_host()
-            .input_devices()
-            .unwrap()
-            .map(|d| d.name().unwrap_or("Unknown Microphone".to_string()))
-            .collect()
+        cpal::default_host()
+            .input_devices()
+            .map(|devices| {
+                devices
+                    .map(|d| d.name().unwrap_or_else(|_| "Unknown Microphone".to_string()))
+                    .collect()
+            })
+            .unwrap_or_else(|err| {
+                tracing::error!("Failed to enumerate input devices in list_devices: {:?}", err);
+                Vec::new()
+            })
plugins/listener/src/fsm.rs (1)

796-824: Handle device change reinitialize failures more defensively.

When MicChange or SpeakerChange triggers resource teardown and reinitialization (lines 801-805, 817-819), failures are only logged. This leaves the session in a torn-down state with no resources and no user notification. Consider transitioning to State::Inactive on failure or emitting an error event to notify the UI.

Example defensive pattern:

 if self.session_id.is_some() && self.tasks.is_some() {
     if let Some(session_id) = self.session_id.clone() {
         self.teardown_resources().await;
         if let Err(e) = self.setup_resources(&session_id).await {
             tracing::error!("Failed to setup resources: {:?}", e);
+            // Transition to inactive since resources are torn down
+            return Transition(State::inactive());
         }
     }
 }
♻️ Duplicate comments (10)
crates/whisper-local/examples/direct_test.rs (1)

4-4: Use generic paths or CLI arguments instead of hardcoded user-specific path.

The hardcoded path /home/benediktb/... makes this example unusable for other developers.

The previous review suggested using dirs::data_dir() or accepting the path as a command-line argument. For reference, crates/transcribe-whisper-local/examples/show_data_dir.rs demonstrates the platform-appropriate data directory approach.

crates/whisper-local/src/model.rs (4)

68-76: Library code should return Result instead of panicking.

Lines 68 and 75 use unwrap() and panic!(), preventing callers from handling errors gracefully.

This issue was previously flagged. Library code should propagate errors via Result<Whisper, Error> rather than panicking.


106-107: Library code should return Result instead of panicking.

The unwrap_or_else with panic on line 106 prevents graceful error handling.

This was previously flagged. The build method should return Result<Whisper, Error> and propagate this error.


111-118: Remove "what" comment and avoid panic.

Line 111's comment violates the coding guideline, and line 118's panic was previously flagged.

Apply this diff to remove the comment:

-            // CPU only
             let mut cpu_params = WhisperContextParameters::default();

The panic issue was previously raised and remains unaddressed.


121-121: Library code should return Result instead of panicking.

The expect() call prevents callers from handling state creation failures.

This was previously flagged. With a Result-returning build() method, propagate this error using ? or map_err.

owhisper/owhisper-server/src/commands/run.rs (1)

17-19: Remove the duplicated function signature.

The second pub async fn handle_run(...) line is still present, so the file won’t compile (Rust rejects nested function definitions). Drop the inner signature so only one definition remains.

 /// Orchestrates audio transcription server with microphone input.
-pub async fn handle_run(args: RunArgs) -> anyhow::Result<()> {
-pub async fn handle_run(args: RunArgs) -> anyhow::Result<()> {
+pub async fn handle_run(args: RunArgs) -> anyhow::Result<()> {
crates/detect/src/browser/linux.rs (1)

45-74: Reset detection set each tick and tighten process matching.

detected_browsers only ever grows, so once (say) Firefox appears you never report it again after a restart. On top of that, stdout.contains(browser) fires on unrelated commands (e.g. “chromedriver”). Build the current set from the ps output each poll, compare against the previous set, and match the process name field instead of a raw substring.

-                        for browser in &BROWSER_NAMES {
-                            if stdout.contains(browser) {
-                                if let Ok(mut detected) = detected_browsers.lock() {
-                                    if !detected.contains(*browser) {
-                                        detected.insert(browser.to_string());
-                                        f(format!("{} running", browser));
-                                    }
-                                }
-                                // Silently continue if mutex is poisoned
-                            }
-                        }
+                        let mut current = std::collections::HashSet::new();
+                        for line in stdout.lines().skip(1) {
+                            if let Some(cmd) = line.split_whitespace().last() {
+                                if let Some(browser) = BROWSER_NAMES.iter().find(|name| *name == &cmd) {
+                                    current.insert(browser.to_string());
+                                }
+                            }
+                        }
+
+                        if let Ok(mut detected) = detected_browsers.lock() {
+                            for browser in current.difference(&*detected) {
+                                f(format!("{} running", browser));
+                            }
+                            *detected = current;
+                        }
crates/audio/src/speaker/linux.rs (1)

37-45: Mock speaker stream is ~480× too slow.

Line 39 only pushes a single sample every 10 ms, yet sample_rate() advertises 48 kHz. Consumers block for seconds waiting for enough data, exactly the issue raised in the earlier review.

Batch the silence so you emit ~480 samples per 10 ms (or adjust the advertised sample_rate). For example:

-            loop {
-                if sender.unbounded_send(0.0).is_err() {
-                    tracing::debug!("SpeakerStream channel closed, exiting thread");
-                    break;
-                }
-
-                thread::sleep(Duration::from_millis(10));
-            }
+            const SAMPLES_PER_BATCH: usize = 480; // 48 kHz / 100 batches per second
+            loop {
+                for _ in 0..SAMPLES_PER_BATCH {
+                    if sender.unbounded_send(0.0).is_err() {
+                        tracing::debug!("SpeakerStream channel closed, exiting thread");
+                        return;
+                    }
+                }
+
+                thread::sleep(Duration::from_millis(10));
+            }
crates/audio/src/lib.rs (2)

227-232: Propagate speaker initialization errors immediately.

If SpeakerInput::new() fails (line 227-230), from_speaker still returns Ok with speaker: None, deferring the error until stream() is called (line 257). This is inconsistent with from_mic which propagates errors immediately. A previous review raised a similar concern about this pattern.

Apply this diff to fail fast:

-    let speaker = match SpeakerInput::new() {
-        Ok(speaker) => { tracing::debug!("Successfully created SpeakerInput"); Some(speaker) }
-        Err(e) => { tracing::error!("Failed to create SpeakerInput: {}", e); None }
-    };
-
-    Ok(Self { source: AudioSource::RealtimeSpeaker, mic: None, speaker, speaker_device_name: None, data: None })
+    let speaker = SpeakerInput::new().map_err(|e| {
+        tracing::error!("Failed to create SpeakerInput: {}", e);
+        crate::Error::StreamInitFailed
+    })?;
+    tracing::debug!("Successfully created SpeakerInput");
+
+    Ok(Self { source: AudioSource::RealtimeSpeaker, mic: None, speaker: Some(speaker), speaker_device_name: None, data: None })

145-157: Wrap Linux-specific pactl command in platform guard.

The pactl command is Linux-specific (PulseAudio/PipeWire) and will fail on macOS/Windows. A previous review flagged this same issue. Wrap this block in #[cfg(target_os = "linux")] to prevent runtime failures on other platforms.

Apply this diff:

         .collect();

+    #[cfg(target_os = "linux")]
+    {
-    // Add virtual echo-cancel device if it exists
-    if std::process::Command::new("pactl")
-        .args(["list", "sources", "short"])
-        .output()
-        .map(|output| String::from_utf8_lossy(&output.stdout).contains("echo-cancel-source"))
-        .unwrap_or(false)
-    {
-        if !result.contains(&"echo-cancel-source".to_string()) {
-            tracing::debug!("Adding virtual echo-cancel-source device");
-            result.push("echo-cancel-source".to_string());
+        if std::process::Command::new("pactl")
+            .args(["list", "sources", "short"])
+            .output()
+            .map(|output| String::from_utf8_lossy(&output.stdout).contains("echo-cancel-source"))
+            .unwrap_or(false)
+        {
+            if !result.contains(&"echo-cancel-source".to_string()) {
+                tracing::debug!("Adding virtual echo-cancel-source device");
+                result.push("echo-cancel-source".to_string());
+            }
         }
     }

     tracing::debug!("Returning {} devices from list_mic_devices", result.len());
🧹 Nitpick comments (12)
crates/whisper-local/src/model.rs (3)

70-70: Remove "what" comment.

This comment explains what the code does rather than why, violating the coding guideline.

As per coding guidelines

Apply this diff:

-        // Log the model path for debugging
         tracing::info!("Loading whisper model from: {}", model_path);

78-78: Remove "what" comment.

This comment explains the implementation rather than the rationale.

As per coding guidelines

Apply this diff:

-        // Try to initialize with GPU first, fall back to CPU if GPU fails
         let backends = crate::list_ggml_backends();

85-90: Remove "what" comment and extract parameter initialization.

Line 85's comment violates the coding guideline. The repeated parameter initialization across lines 86-90, 99-102, and 112-115 introduces duplication.

As per coding guidelines

Extract a helper function:

fn create_whisper_params(use_gpu: bool) -> WhisperContextParameters {
    let mut params = WhisperContextParameters::default();
    params.use_gpu = use_gpu;
    if use_gpu {
        params.gpu_device = 0;
    }
    params.flash_attn = false;
    params.dtw_parameters.mode = whisper_rs::DtwMode::None;
    params
}

Then simplify the initialization:

-            // Try GPU first
-            let mut gpu_params = WhisperContextParameters::default();
-            gpu_params.gpu_device = 0;
-            gpu_params.use_gpu = true;
-            gpu_params.flash_attn = false;
-            gpu_params.dtw_parameters.mode = whisper_rs::DtwMode::None;
+            let gpu_params = create_whisper_params(true);
crates/whisper-local/examples/list_backends.rs (1)

3-18: Remove redundant documentation.

The doc comment duplicates the implementation below and is unusual for an example binary. Doc comments are typically reserved for library APIs, not example executables.

Apply this diff:

-/// Lists available GGML backends and prints their kind, name, description, and memory stats.
-///
-/// # Examples
-///
-/// ```
-/// // Run the example binary to print detected backends to stdout.
-/// fn main() {
-///     let backends = whisper_local::list_ggml_backends();
-///     println!("Available backends:");
-///     for backend in backends {
-///         println!("  {}: {} - {} ({} MB free / {} MB total)",
-///                  backend.kind, backend.name, backend.description,
-///                  backend.free_memory_mb, backend.total_memory_mb);
-///     }
-/// }
-/// ```
 fn main() {
AGENTS.md (1)

60-62: Consider varying sentence structure.

The three consecutive sentences beginning with "Do not" could be reworded for better flow.

Apply this diff to vary the structure:

 ## Do Not
 - Do not commit large model binaries.
-- Do not add new formatters or global toolchains without discussion.
-- Do not enable heavy features for simple type export or CI smoke tests.
+- Avoid adding new formatters or global toolchains without discussion.
+- Keep heavy features disabled for simple type export or CI smoke tests.
crates/detect/src/mic/linux.rs (1)

48-68: Avoid blocking the async runtime with std::process::Command.

This background task runs on Tokio (note the async move and tokio::select!), but std::process::Command::output() is fully blocking. If pactl ever stalls—even briefly—you tie up a scheduler thread, delaying every other task on that worker. Please move the PulseAudio probe onto an async-friendly path (e.g. tokio::process::Command) or wrap it in spawn_blocking.

Apply this diff to switch to Tokio’s process API:

- use std::process::Command;
+ use tokio::process::Command;
@@
-                        if is_microphone_in_use() {
+                        if is_microphone_in_use().await {
@@
-fn is_microphone_in_use() -> bool {
-    // Check if any source-outputs exist (applications using microphone)
-    if let Ok(output) = Command::new("pactl")
-        .args(["list", "source-outputs", "short"])
-        .output()
-    {
+async fn is_microphone_in_use() -> bool {
+    // Check if any source-outputs exist (applications using microphone)
+    if let Ok(output) = Command::new("pactl")
+        .args(["list", "source-outputs", "short"])
+        .output()
+        .await
+    {

Also applies to: 99-108

crates/detect/src/browser/mod.rs (1)

39-41: Prefer structured logging over eprintln!.

This module otherwise uses structured logging, but eprintln! bypasses that and forces stderr noise on consumers embedding the detector. Please route the failure through tracing::warn! (or the crate’s chosen logger) so integrators can manage log levels properly.

crates/audio/src/speaker/mod.rs (1)

32-32: Remove "what" comments that duplicate obvious function signatures.

Per coding guidelines, comments should explain "why" not "what". These doc comments simply restate what the function signatures and cfg attributes already convey. Remove lines 32, 39, 47, 54, 71, 89, 94, and 100.

Apply this diff:

-    /// Initialize platform-specific speaker capture
     #[cfg(any(target_os = "macos", target_os = "windows", target_os = "linux"))]
     pub fn new() -> Result<Self> {
         let inner = PlatformSpeakerInput::new()?;
         Ok(Self { inner })
     }

-    /// Unsupported platforms return an error
     #[cfg(not(any(target_os = "macos", target_os = "windows", target_os = "linux")))]
     pub fn new() -> Result<Self> {
         Err(anyhow::anyhow!(
             "'SpeakerInput::new' is not supported on this platform"
         ))
     }

-    /// Consume input and open speaker stream
     #[cfg(any(target_os = "macos", target_os = "windows", target_os = "linux"))]
     pub fn stream(self) -> Result<SpeakerStream> {
         let inner = self.inner.stream();
         Ok(SpeakerStream { inner })
     }

-    /// Not supported on this platform
     #[cfg(not(any(target_os = "macos", target_os = "windows", target_os = "linux")))]
     pub fn stream(self) -> Result<SpeakerStream> {
         Err(anyhow::anyhow!(
             "'SpeakerInput::stream' is not supported on this platform"
         ))
     }
-    /// Poll for next audio sample
     fn poll_next(
         self: std::pin::Pin<&mut Self>,
         cx: &mut std::task::Context<'_>,
     ) -> std::task::Poll<Option<Self::Item>> {
-    /// Expose as async stream of f32 samples
     fn as_stream(&mut self) -> impl Stream<Item = f32> + '_ {
         self
     }

-    /// Sample rate in Hz
     #[cfg(any(target_os = "macos", target_os = "windows", target_os = "linux"))]
     fn sample_rate(&self) -> u32 {
         self.inner.sample_rate()
     }

-    /// Sample rate unavailable on unsupported targets
     #[cfg(not(any(target_os = "macos", target_os = "windows", target_os = "linux")))]
     fn sample_rate(&self) -> u32 {
         0
     }

Also applies to: 39-39, 47-47, 54-54, 71-71, 89-89, 94-94, 100-100

plugins/listener/src/fsm.rs (1)

205-228: Remove verbose "what" documentation that duplicates obvious signatures.

Per coding guidelines, comments should be minimal and explain "why" not "what". These extensive doc comment blocks (lines 205-228, 692-709, 749-778, 930-941) simply restate what the function signatures, parameter types, and return types already convey. The function names (setup_resources, update_session, common, on_transition) are self-explanatory, and the implementation shows the behavior.

Also applies to: 692-709, 749-778, 930-941

crates/audio/src/lib.rs (3)

86-86: Remove redundant "what" comments.

Per coding guidelines, comments should explain "why" not "what". Lines 86, 96, 106-109, and 171-174 simply restate what the function names already convey (get_default_mic_device_name, get_default_speaker_device_name, list_mic_devices, list_speaker_devices).

Also applies to: 96-96, 106-109, 171-174


113-124: Simplify error handling chain for device enumeration.

Lines 115-124 use confusing chaining: map for success (115-119), then map_err for error (120-123), then unwrap_or_else (124). The map already collects success into Vec<cpal::Device>, so the subsequent map_err doesn't transform the error in a useful way before unwrap_or_else swallows it. Simplify:

     let devices: Vec<cpal::Device> = host
         .input_devices()
-        .map(|devices| {
-            let device_vec: Vec<cpal::Device> = devices.collect();
-            tracing::debug!("Found {} input devices in list_mic_devices", device_vec.len());
-            device_vec
-        })
-        .map_err(|e| {
-            tracing::error!("Failed to enumerate input devices in list_mic_devices: {:?}", e);
-            e
-        })
-        .unwrap_or_else(|_| Vec::new());
+        .map(|devices| devices.collect::<Vec<_>>())
+        .unwrap_or_else(|e| {
+            tracing::error!("Failed to enumerate input devices in list_mic_devices: {:?}", e);
+            Vec::new()
+        });
+    tracing::debug!("Found {} input devices in list_mic_devices", devices.len());

212-218: Reduce logging verbosity in from_mic.

Two tracing calls (info + debug) for a single operation is excessive. Use debug level for both or consolidate into one call.

 pub fn from_mic(device_name: Option<String>) -> Result<Self, crate::Error> {
-    tracing::info!("Creating AudioInput from microphone with device name: {:?}", device_name);
+    tracing::debug!("Creating AudioInput from microphone: {:?}", device_name);
     let mic = MicInput::new(device_name)?;
-    tracing::debug!("Successfully created MicInput");

     Ok(Self { source: AudioSource::RealtimeMic, mic: Some(mic), speaker: None, speaker_device_name: None, data: None })
 }
📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 44f163e and f4e86be.

⛔ Files ignored due to path filters (1)
  • Cargo.lock is excluded by !**/*.lock
📒 Files selected for processing (38)
  • .gitignore (1 hunks)
  • AGENTS.md (1 hunks)
  • LINUX_AUDIO.md (1 hunks)
  • LINUX_SUPPORT.md (1 hunks)
  • LinuxInstallNotes.md (1 hunks)
  • crates/audio/src/bin/simple_test.rs (1 hunks)
  • crates/audio/src/bin/test_mic.rs (1 hunks)
  • crates/audio/src/bin/test_speaker.rs (1 hunks)
  • crates/audio/src/errors.rs (1 hunks)
  • crates/audio/src/lib.rs (2 hunks)
  • crates/audio/src/mic.rs (4 hunks)
  • crates/audio/src/speaker/linux.rs (1 hunks)
  • crates/audio/src/speaker/mod.rs (3 hunks)
  • crates/audio/src/speaker/windows.rs (4 hunks)
  • crates/detect/src/app/linux.rs (1 hunks)
  • crates/detect/src/app/mod.rs (1 hunks)
  • crates/detect/src/browser/linux.rs (1 hunks)
  • crates/detect/src/browser/mod.rs (2 hunks)
  • crates/detect/src/mic/linux.rs (1 hunks)
  • crates/detect/src/mic/mod.rs (1 hunks)
  • crates/file/examples/checksum.rs (1 hunks)
  • crates/transcribe-whisper-local/examples/show_data_dir.rs (1 hunks)
  • crates/whisper-local/examples/direct_test.rs (1 hunks)
  • crates/whisper-local/examples/list_backends.rs (1 hunks)
  • crates/whisper-local/examples/test_model.rs (1 hunks)
  • crates/whisper-local/src/model.rs (1 hunks)
  • owhisper/owhisper-server/src/commands/run.rs (3 hunks)
  • plugins/connector/Cargo.toml (1 hunks)
  • plugins/connector/src/error.rs (1 hunks)
  • plugins/connector/src/ext.rs (3 hunks)
  • plugins/listener/Cargo.toml (3 hunks)
  • plugins/listener/js/bindings.gen.ts (2 hunks)
  • plugins/listener/src/commands.rs (3 hunks)
  • plugins/listener/src/error.rs (1 hunks)
  • plugins/listener/src/events.rs (1 hunks)
  • plugins/listener/src/ext.rs (6 hunks)
  • plugins/listener/src/fsm.rs (17 hunks)
  • plugins/listener/src/lib.rs (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (9)
  • crates/file/examples/checksum.rs
  • crates/whisper-local/examples/test_model.rs
  • crates/detect/src/app/linux.rs
  • crates/transcribe-whisper-local/examples/show_data_dir.rs
  • LinuxInstallNotes.md
  • crates/audio/src/bin/test_speaker.rs
  • crates/audio/src/bin/simple_test.rs
  • plugins/listener/src/error.rs
  • crates/detect/src/app/mod.rs
🧰 Additional context used
📓 Path-based instructions (1)
**/*.{js,ts,tsx,rs}

⚙️ CodeRabbit configuration file

**/*.{js,ts,tsx,rs}: 1. No error handling.
2. No unused imports, variables, or functions.
3. For comments, keep it minimal. It should be about "Why", not "What".

Files:

  • plugins/listener/src/events.rs
  • crates/whisper-local/examples/list_backends.rs
  • crates/audio/src/mic.rs
  • crates/detect/src/mic/linux.rs
  • plugins/listener/js/bindings.gen.ts
  • plugins/listener/src/commands.rs
  • crates/audio/src/speaker/linux.rs
  • crates/whisper-local/src/model.rs
  • plugins/listener/src/ext.rs
  • crates/audio/src/errors.rs
  • plugins/connector/src/error.rs
  • crates/whisper-local/examples/direct_test.rs
  • owhisper/owhisper-server/src/commands/run.rs
  • crates/detect/src/browser/linux.rs
  • crates/audio/src/speaker/mod.rs
  • crates/detect/src/browser/mod.rs
  • crates/audio/src/lib.rs
  • plugins/listener/src/fsm.rs
  • crates/audio/src/bin/test_mic.rs
  • plugins/connector/src/ext.rs
  • crates/audio/src/speaker/windows.rs
  • crates/detect/src/mic/mod.rs
  • plugins/listener/src/lib.rs
🧬 Code graph analysis (17)
crates/audio/src/mic.rs (1)
crates/audio/src/lib.rs (2)
  • sample_rate (310-316)
  • device_name (239-248)
crates/detect/src/mic/linux.rs (3)
crates/detect/src/app/linux.rs (2)
  • start (61-98)
  • stop (109-111)
crates/detect/src/browser/linux.rs (2)
  • start (29-79)
  • stop (82-86)
crates/detect/src/mic/mod.rs (2)
  • start (21-23)
  • stop (24-26)
plugins/listener/js/bindings.gen.ts (2)
plugins/db/js/bindings.gen.ts (2)
  • Word2 (182-182)
  • SpeakerIdentity (178-178)
plugins/local-stt/js/bindings.gen.ts (1)
  • SpeakerIdentity (65-65)
plugins/listener/src/commands.rs (3)
crates/audio/src/lib.rs (2)
  • list_speaker_devices (175-200)
  • device_name (239-248)
plugins/listener/src/ext.rs (8)
  • list_speaker_devices (21-21)
  • list_speaker_devices (57-59)
  • get_current_speaker_device (22-24)
  • get_current_speaker_device (70-74)
  • set_speaker_device (25-28)
  • set_speaker_device (94-107)
  • set_default_speaker_device (29-29)
  • set_default_speaker_device (110-119)
plugins/listener/src/fsm.rs (1)
  • get_current_speaker_device (638-640)
crates/audio/src/speaker/linux.rs (3)
crates/audio/src/mic.rs (6)
  • mpsc (402-402)
  • new (215-236)
  • stream (401-480)
  • sample_rate (519-521)
  • poll_next (499-511)
  • drop (491-493)
crates/audio/src/speaker/mod.rs (7)
  • new (34-37)
  • new (41-45)
  • stream (49-52)
  • stream (56-60)
  • sample_rate (96-98)
  • sample_rate (102-104)
  • poll_next (72-85)
crates/audio/src/lib.rs (3)
  • stream (250-266)
  • sample_rate (310-316)
  • poll_next (278-302)
crates/whisper-local/src/model.rs (2)
plugins/local-stt/src/ext.rs (2)
  • list_ggml_backends (14-14)
  • list_ggml_backends (49-51)
crates/whisper-local/src/lib.rs (1)
  • list_ggml_backends (22-67)
plugins/listener/src/ext.rs (3)
crates/audio/src/lib.rs (5)
  • list_speaker_devices (175-200)
  • device_name (239-248)
  • get_default_speaker_device_name (97-104)
  • from_mic (212-218)
  • from_speaker (222-233)
plugins/listener/src/commands.rs (4)
  • list_speaker_devices (15-21)
  • get_current_speaker_device (35-41)
  • set_speaker_device (56-63)
  • set_default_speaker_device (67-73)
plugins/listener/src/fsm.rs (3)
  • get_current_speaker_device (638-640)
  • new (75-115)
  • new (185-203)
plugins/connector/src/error.rs (1)
plugins/connector/src/types.rs (2)
  • from (23-29)
  • from (43-48)
crates/whisper-local/examples/direct_test.rs (3)
crates/file/examples/checksum.rs (1)
  • main (18-30)
crates/transcribe-whisper-local/examples/show_data_dir.rs (1)
  • main (4-18)
crates/whisper-local/examples/test_model.rs (1)
  • main (14-32)
owhisper/owhisper-server/src/commands/run.rs (2)
crates/audio/src/mic.rs (2)
  • new (215-236)
  • device_name (166-170)
crates/audio/src/lib.rs (1)
  • device_name (239-248)
crates/detect/src/browser/linux.rs (4)
crates/detect/src/app/linux.rs (3)
  • default (33-37)
  • start (61-98)
  • stop (109-111)
crates/detect/src/mic/linux.rs (3)
  • default (17-21)
  • start (47-69)
  • stop (81-83)
crates/detect/src/app/mod.rs (2)
  • start (21-23)
  • stop (24-26)
crates/detect/src/browser/mod.rs (2)
  • start (21-23)
  • stop (24-26)
crates/audio/src/speaker/mod.rs (5)
crates/audio/src/mic.rs (4)
  • new (215-236)
  • stream (401-480)
  • poll_next (499-511)
  • sample_rate (519-521)
crates/audio/src/speaker/linux.rs (5)
  • new (12-17)
  • new (31-52)
  • stream (19-22)
  • poll_next (62-65)
  • sample_rate (54-56)
crates/audio/src/speaker/windows.rs (4)
  • new (14-16)
  • stream (18-45)
  • poll_next (201-252)
  • sample_rate (61-63)
crates/audio/src/speaker/macos.rs (4)
  • new (48-96)
  • stream (148-176)
  • poll_next (182-201)
  • sample_rate (36-38)
crates/audio/src/lib.rs (3)
  • stream (250-266)
  • poll_next (278-302)
  • sample_rate (310-316)
crates/audio/src/lib.rs (8)
crates/audio/src/mic.rs (8)
  • device (69-69)
  • device (75-75)
  • device (81-81)
  • device (87-87)
  • device (415-415)
  • new (215-236)
  • device_name (166-170)
  • stream (401-480)
crates/audio/src/speaker/linux.rs (3)
  • new (12-17)
  • new (31-52)
  • stream (19-22)
crates/audio/src/speaker/mod.rs (4)
  • new (34-37)
  • new (41-45)
  • stream (49-52)
  • stream (56-60)
crates/audio/src/speaker/windows.rs (2)
  • new (14-16)
  • stream (18-45)
plugins/listener/src/fsm.rs (2)
  • new (75-115)
  • new (185-203)
crates/audio/src/speaker/macos.rs (2)
  • new (48-96)
  • stream (148-176)
plugins/listener/src/commands.rs (1)
  • list_speaker_devices (15-21)
plugins/listener/src/ext.rs (2)
  • list_speaker_devices (21-21)
  • list_speaker_devices (57-59)
plugins/listener/src/fsm.rs (3)
crates/audio/src/lib.rs (5)
  • get_default_speaker_device_name (97-104)
  • from_speaker (222-233)
  • stream (250-266)
  • list_speaker_devices (175-200)
  • device_name (239-248)
plugins/listener/src/commands.rs (2)
  • list_speaker_devices (15-21)
  • get_current_speaker_device (35-41)
plugins/listener/src/ext.rs (4)
  • list_speaker_devices (21-21)
  • list_speaker_devices (57-59)
  • get_current_speaker_device (22-24)
  • get_current_speaker_device (70-74)
crates/audio/src/bin/test_mic.rs (2)
crates/audio/src/lib.rs (4)
  • list_mic_devices (110-160)
  • get_default_mic_device_name (87-94)
  • from_mic (212-218)
  • device_name (239-248)
crates/audio/src/mic.rs (6)
  • device (69-69)
  • device (75-75)
  • device (81-81)
  • device (87-87)
  • device (415-415)
  • device_name (166-170)
plugins/connector/src/ext.rs (3)
plugins/local-stt/src/ext.rs (8)
  • api_base (15-15)
  • api_base (53-58)
  • state (54-54)
  • state (124-124)
  • state (150-150)
  • state (161-161)
  • state (200-200)
  • state (214-214)
plugins/local-llm/src/ext.rs (8)
  • api_base (12-12)
  • api_base (46-50)
  • state (47-47)
  • state (54-54)
  • state (83-83)
  • state (118-118)
  • state (170-170)
  • state (189-189)
plugins/connector/js/bindings.gen.ts (2)
  • ConnectionLLM (113-113)
  • Connection (112-112)
plugins/listener/src/lib.rs (5)
plugins/listener/js/bindings.gen.ts (1)
  • commands (9-76)
crates/audio/src/lib.rs (1)
  • list_speaker_devices (175-200)
plugins/listener/src/commands.rs (6)
  • list_speaker_devices (15-21)
  • get_current_microphone_device (25-31)
  • get_current_speaker_device (35-41)
  • set_microphone_device (45-52)
  • set_speaker_device (56-63)
  • set_default_speaker_device (67-73)
plugins/listener/src/ext.rs (12)
  • list_speaker_devices (21-21)
  • list_speaker_devices (57-59)
  • get_current_microphone_device (13-15)
  • get_current_microphone_device (63-67)
  • get_current_speaker_device (22-24)
  • get_current_speaker_device (70-74)
  • set_microphone_device (16-19)
  • set_microphone_device (78-91)
  • set_speaker_device (25-28)
  • set_speaker_device (94-107)
  • set_default_speaker_device (29-29)
  • set_default_speaker_device (110-119)
plugins/listener/src/fsm.rs (1)
  • get_current_speaker_device (638-640)
🪛 LanguageTool
AGENTS.md

[style] ~62-~62: Three successive sentences begin with the same word. Consider rewording the sentence or use a thesaurus to find a synonym.
Context: ...global toolchains without discussion. - Do not enable heavy features for simple ty...

(ENGLISH_WORD_REPEAT_BEGINNING_RULE)

LINUX_AUDIO.md

[style] ~26-~26: ‘mixed together’ might be wordy. Consider a shorter alternative.
Context: ...rophone audio and the speaker audio are mixed together. * Audio levels (amplitude) are c...

(EN_WORDINESS_PREMIUM_MIXED_TOGETHER)

🪛 markdownlint-cli2 (0.18.1)
LINUX_SUPPORT.md

42-42: Unordered list indentation
Expected: 2; Actual: 4

(MD007, ul-indent)


43-43: Unordered list indentation
Expected: 2; Actual: 4

(MD007, ul-indent)

LINUX_AUDIO.md

54-54: Unordered list indentation
Expected: 2; Actual: 4

(MD007, ul-indent)


55-55: Unordered list indentation
Expected: 2; Actual: 4

(MD007, ul-indent)


56-56: Unordered list indentation
Expected: 2; Actual: 4

(MD007, ul-indent)

🔇 Additional comments (10)
crates/whisper-local/examples/list_backends.rs (1)

19-32: LGTM!

The example clearly demonstrates backend enumeration with well-formatted output.

.gitignore (1)

21-22: LGTM!

The new ignore entry for Linux audio artifacts aligns well with the audio development work described in the PR.

AGENTS.md (1)

1-58: LGTM!

The agent guidance documentation is comprehensive and well-organized, covering all essential aspects of working with the polyglot monorepo.

crates/audio/src/errors.rs (1)

6-19: LGTM!

The new error variants are well-structured and provide comprehensive coverage for audio I/O error scenarios. The error messages are clear and the use of thiserror is idiomatic.

plugins/connector/src/error.rs (1)

7-12: LGTM!

The feature gating for LocalLlmError and LocalSttError is correctly implemented and aligns with the optional dependency strategy outlined in the PR.

LINUX_SUPPORT.md (1)

1-127: LGTM!

Excellent comprehensive documentation of Linux support status. The document clearly outlines current capabilities, gaps, and next steps. The recent improvements section (lines 5-22) provides valuable context on robustness enhancements.

plugins/connector/src/ext.rs (2)

93-116: LGTM!

The feature gating for local LLM connection is correctly implemented. The code properly handles both cases: returning a connection when the feature is enabled, and a clear error message when disabled.


222-244: LGTM!

The feature gating for local STT connection follows the same pattern as the LLM implementation and is correctly structured.

LINUX_AUDIO.md (1)

1-68: LGTM!

Excellent technical documentation of the Linux audio implementation status. The document clearly explains the current mock implementation, processing pipeline, and provides a clear roadmap with the recent improvements section (lines 42-59) highlighting the robustness work already completed.

plugins/listener/src/events.rs (1)

26-27: LGTM!

The new SpeakerDeviceChanged event variant is properly structured and follows the existing patterns in the enum. The optional name field appropriately handles cases where the device name may not be available.


.windsurfrules
CLAUDE.md
CLAUDE.md
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

Verify the leading space is intentional.

The ignore pattern has a leading space (CLAUDE.md), which is unusual for gitignore entries. This likely should be CLAUDE.md without leading/trailing spaces, unless the filename itself contains spaces.


🏁 Script executed:

#!/bin/bash
# Check if CLAUDE.md file exists and verify its exact name
fd -H -t f "CLAUDE.md" -x echo "Found: '{}'"

Length of output: 0


🏁 Script executed:

#!/bin/bash
# Display .gitignore content around line 19 with visible whitespace
sed -n '17,23p' .gitignore | cat -A

echo "---"

# Check for any files with leading whitespace in their names
fd -H --hidden -x sh -c 'case "$1" in " "*) echo "File with leading space: $1" ;; esac' _ {}

Length of output: 97


Remove the leading space from line 19 in .gitignore.

The pattern CLAUDE.md contains a leading space, causing gitignore to match only files literally named " CLAUDE.md" (with a leading space). Since no such file exists in the repository, this pattern is ineffective. Change it to CLAUDE.md to match the intended filename.

🤖 Prompt for AI Agents
In .gitignore around line 19, the entry contains a leading space (" CLAUDE.md")
so it only matches a filename with a leading space; remove the leading space so
the line reads "CLAUDE.md" to correctly ignore the CLAUDE.md file.

Comment on lines 57 to 65
fn validate_device_with_fallback(device: &cpal::Device) -> Option<cpal::SupportedStreamConfig> {
// Try common configurations first
if let Some(config) = validate_against_common_configs(device) {
return Some(config);
}

// Fall back to standard F32 config
Some(create_standard_config(48000, cpal::SampleFormat::F32))
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Don’t return an unvalidated “fallback” stream config.

validate_device_with_fallback currently hands back create_standard_config(48000, F32) without testing it. When none of the common presets work (for example, a mono‑only microphone), MicInput::new still succeeds, but MicInput::stream() later fails to build the CPAL stream. That leaves callers with an apparently healthy MicInput that can never produce audio.

Please either validate the fallback config or bail out early; using device.default_input_config() is a safe option:

Apply this diff so we only return configs that CPAL reports as supported:

 fn validate_device_with_fallback(device: &cpal::Device) -> Option<cpal::SupportedStreamConfig> {
     // Try common configurations first
     if let Some(config) = validate_against_common_configs(device) {
         return Some(config);
     }
 
-    // Fall back to standard F32 config
-    Some(create_standard_config(48000, cpal::SampleFormat::F32))
+    match device.default_input_config() {
+        Ok(config) => Some(config),
+        Err(err) => {
+            tracing::warn!(
+                "Unable to obtain default input config during fallback: {:?}",
+                err
+            );
+            None
+        }
+    }
 }
🤖 Prompt for AI Agents
In crates/audio/src/mic.rs around lines 57 to 65, the function currently returns
an unvalidated fallback config from create_standard_config(48000, F32); change
it to only return configs CPAL reports as supported by either (a) attempting to
use device.default_input_config() if available, or (b) enumerating
device.supported_input_configs() and matching a config equivalent to the
fallback (or using validate_against_common_configs result) and returning
Some(config) only if CPAL confirms support, otherwise return None so
MicInput::new can fail early; in short, replace the unconditional fallback with
a validated default-input-query or supported-config check and return None when
no supported config is found.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (3)
crates/audio/src/bin/test_speaker_extended.rs (1)

12-12: Remove "what" comments; keep only "why" explanations.

Several comments describe what the code does rather than why, violating the coding guideline: "For comments, keep it minimal. It should be about 'Why', not 'What'."

As per coding guidelines.

Consider removing these comments:

  • Line 12: "Create speaker audio input"
  • Line 16: "Create stream"
  • Line 20: "Test actual audio capture"
  • Line 29: "Capture audio for a few seconds"
  • Line 36: "Print progress every 0.5 seconds at 48kHz"
  • Line 43: "Stop after ~3 seconds at 48kHz"

The code is self-explanatory without them.

Also applies to: 16-16, 20-20, 29-29, 36-36, 43-43

crates/audio/src/speaker/linux.rs (2)

40-40: Remove or rewrite "what" comments to explain "why".

Multiple comments describe what the code does rather than why, violating the coding guideline: "For comments, keep it minimal. It should be about 'Why', not 'What'."

As per coding guidelines.

Consider removing or rewriting these comments:

  • Line 40: "Try PulseAudio first" → remove (obvious from control flow)
  • Line 57: "Query PulseAudio for monitor sources" → remove (function name is clear)
  • Line 72: "Find the first monitor source..." → remove (code is self-explanatory)
  • Line 111: Keep the TODO as is
  • Line 159: "Read audio data from PulseAudio" → remove
  • Line 165: "Convert bytes to f32 samples and send to stream" → remove
  • Line 168: "For stereo, we'll take the average..." → remove (code is clear)

Note: Line 201's comment is good because it explains why this approach avoids busy-looping.

Also applies to: 57-57, 72-72, 111-111, 159-159, 165-165, 168-168


156-156: Clarify buffer size comment for stereo frames.

The comment says "Buffer for 1024 f32 samples" but with 2-channel stereo audio, this is actually 512 stereo frames (each frame contains 2 samples). Consider clarifying to avoid confusion about frame vs. sample terminology.

-        let mut buffer = vec![0u8; 1024 * std::mem::size_of::<f32>()]; // Buffer for 1024 f32 samples
+        let mut buffer = vec![0u8; 1024 * std::mem::size_of::<f32>()]; // 1024 f32 samples = 512 stereo frames
📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between f4e86be and 3004678.

⛔ Files ignored due to path filters (1)
  • Cargo.lock is excluded by !**/*.lock
📒 Files selected for processing (7)
  • LINUX_AUDIO.md (1 hunks)
  • LINUX_SUPPORT.md (1 hunks)
  • LinuxInstallNotes.md (1 hunks)
  • crates/audio/Cargo.toml (3 hunks)
  • crates/audio/src/bin/test_speaker_extended.rs (1 hunks)
  • crates/audio/src/errors.rs (1 hunks)
  • crates/audio/src/speaker/linux.rs (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • LinuxInstallNotes.md
🧰 Additional context used
📓 Path-based instructions (1)
**/*.{js,ts,tsx,rs}

⚙️ CodeRabbit configuration file

**/*.{js,ts,tsx,rs}: 1. No error handling.
2. No unused imports, variables, or functions.
3. For comments, keep it minimal. It should be about "Why", not "What".

Files:

  • crates/audio/src/bin/test_speaker_extended.rs
  • crates/audio/src/errors.rs
  • crates/audio/src/speaker/linux.rs
🧬 Code graph analysis (2)
crates/audio/src/bin/test_speaker_extended.rs (2)
crates/audio/src/lib.rs (1)
  • from_speaker (222-233)
crates/audio/src/speaker/linux.rs (1)
  • stream (86-89)
crates/audio/src/speaker/linux.rs (4)
crates/audio/src/mic.rs (6)
  • mpsc (402-402)
  • new (215-236)
  • stream (401-480)
  • sample_rate (519-521)
  • poll_next (499-511)
  • drop (491-493)
crates/audio/src/speaker/mod.rs (7)
  • new (34-37)
  • new (41-45)
  • stream (49-52)
  • stream (56-60)
  • sample_rate (96-98)
  • sample_rate (102-104)
  • poll_next (72-85)
crates/audio/src/speaker/windows.rs (5)
  • new (14-16)
  • stream (18-45)
  • sample_rate (61-63)
  • poll_next (201-252)
  • drop (182-196)
crates/audio/src/lib.rs (3)
  • stream (250-266)
  • sample_rate (310-316)
  • poll_next (278-302)
🪛 LanguageTool
LINUX_AUDIO.md

[style] ~56-~56: ‘mixed together’ might be wordy. Consider a shorter alternative.
Context: ...rophone audio and the speaker audio are mixed together. * Audio levels (amplitude) are c...

(EN_WORDINESS_PREMIUM_MIXED_TOGETHER)


[grammar] ~98-~98: Use a hyphen to join words.
Context: ...ilize the new helper functions and error handling patterns established in the rec...

(QB_NEW_EN_HYPHEN)

🪛 markdownlint-cli2 (0.18.1)
LINUX_AUDIO.md

55-55: Unordered list indentation
Expected: 2; Actual: 4

(MD007, ul-indent)


56-56: Unordered list indentation
Expected: 2; Actual: 4

(MD007, ul-indent)

🔇 Additional comments (8)
crates/audio/Cargo.toml (1)

6-8: Feature configuration looks good.

The pulseaudio feature is properly configured with optional dependencies, and setting it as default for Linux audio support is a reasonable choice. The dep: prefix correctly gates the dependencies.

crates/audio/src/errors.rs (1)

6-22: LGTM!

The expanded error variants provide comprehensive coverage for audio system failures, including device enumeration, permissions, stream initialization, and system-level errors. The error messages are clear and actionable.

LINUX_SUPPORT.md (1)

1-150: LGTM!

The documentation clearly outlines Linux support status, accurately reflects the implemented PulseAudio speaker capture, and provides helpful installation instructions and testing notes. The structure and content align well with the code changes in this PR.

LINUX_AUDIO.md (1)

1-98: LGTM!

This documentation provides comprehensive coverage of the Linux audio implementation status, including PulseAudio integration, testing procedures, the audio processing pipeline, and recent improvements. It accurately reflects the code implementation.

crates/audio/src/speaker/linux.rs (4)

28-35: LGTM!

The new() method properly returns a Result, performs backend detection with logging, and provides a clean initialization path for Linux speaker input. The error propagation is well-structured.


127-179: LGTM!

The PulseAudio capture implementation is solid: it validates the audio spec, creates a capture stream from the monitor source, reads audio data in a loop, converts stereo to mono via averaging, and handles errors gracefully. The use of bytemuck for safe byte-to-sample conversion is appropriate.


200-203: LGTM!

Delegating to receiver.poll_next_unpin(cx) properly leverages the unbounded channel's async-aware polling, ensuring the waker is registered correctly and avoiding the busy-loop issue that was flagged in previous reviews.


54-84: No changes required; pactl output format handling is robust.

The parsing logic is sound. PulseAudio explicitly documents the "list short" format for script parsing, where the source name is consistently at split_whitespace().nth(1). The code already has comprehensive error handling with .map_err() at each potential failure point, and the caller gracefully falls back to Mock backend if the operation fails—ensuring the system continues functioning even if the format unexpectedly changes.

}
}).await;

let final_rms = (rms_sum / sample_count as f32).sqrt();
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Guard against division by zero.

If the audio stream produces no samples, sample_count remains 0, causing a division-by-zero panic when calculating final_rms.

Apply this diff to add a guard:

-            let final_rms = (rms_sum / sample_count as f32).sqrt();
+            let final_rms = if sample_count > 0 {
+                (rms_sum / sample_count as f32).sqrt()
+            } else {
+                0.0
+            };
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
let final_rms = (rms_sum / sample_count as f32).sqrt();
let final_rms = if sample_count > 0 {
(rms_sum / sample_count as f32).sqrt()
} else {
0.0
};
🤖 Prompt for AI Agents
In crates/audio/src/bin/test_speaker_extended.rs around line 49, the computation
let final_rms = (rms_sum / sample_count as f32).sqrt(); can divide by zero if
sample_count is 0; guard by checking sample_count == 0 and set final_rms to 0.0
(or another sensible default) in that case, otherwise perform the division and
sqrt with sample_count as f32, ensuring no division-by-zero panic.

…tegration

- Add comprehensive Linux notification support via org.freedesktop.Notifications D-Bus interface
- Implement permission checking and multi-desktop environment support (GNOME, KDE, XFCE, MATE, Cinnamon)
- Add thread-safe callback mechanism with proper Send bounds
- Update documentation to reflect notification system implementation status
- Tested and verified on Hyprland with notification daemon
…ugin

- Resolve runtime error where listener plugin couldn't start sessions due to missing local-stt feature
- Enable local-llm and local-stt features on tauri-plugin-connector dependency
- Ensures connector can properly access local STT/LLM servers
- Remove LINUX_AUDIO.md and LINUX_SUPPORT.md (information was duplicated and outdated)
- Create comprehensive linuxtodo.md consolidating all Linux issues, missing features, and TODOs
- Document critical issues: recording session failures, system tray D-Bus issues, audio pipeline testing needs
- Organize by priority: Critical Issues, Missing Features, Build/Packaging, Testing, Documentation
- Include implementation roadmap with 5 phases
- Add status summary showing 85% core functionality complete
- Add environment variable initialization for XDG_RUNTIME_DIR and DBUS_SESSION_BUS_ADDRESS
- Implement monitor detection fallback for Wayland compositors (Hyprland)
- Clean up audio backend detection and logging
- Fix duplicate function declaration in owhisper run command
- Update Linux todo documentation with resolved issues

These changes fix the core functionality issues preventing the app from starting
properly on Wayland-based systems with PipeWire/PulseAudio.
- Add Linux-specific speaker device parameter handling (always use default)
- Format code with cargo fmt for consistency
- Improve error messages and logging formatting
- Fix whitespace issues in listener FSM
Critical fix: jq was being used in 'Validate version' step before being
installed in 'Install system dependencies' step, causing all workflows
to fail with 'jq: command not found'.

Added 'Install jq' step immediately after checkout in:
- linux_packages.yaml (both build-linux-packages and build-appimage jobs)
- linux_packages_rpm.yaml

Arch workflow doesn't need this fix as it uses jq inside Docker container.
Arch workflow also needs jq installed on the runner before the validation
step. The Docker container has jq, but validation runs before Docker.
RPM workflow runs in Fedora container, so need to use dnf package
manager instead of apt-get, and no sudo in container.
Tauri config files are located in apps/desktop/src-tauri/, not ./src-tauri/.
Updated all three workflows to use correct path.
When using 'pnpm -F desktop', the command runs in the apps/desktop
directory context, so config paths must be relative to that directory.
Changed from './apps/desktop/src-tauri/tauri.conf.*.json' to
'./src-tauri/tauri.conf.*.json' in all three Linux packaging workflows.
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

♻️ Duplicate comments (3)
.github/workflows/linux_packages_arch.yaml (1)

373-373: Upgrade deprecated GitHub Actions version — softprops/action-gh-release@v1.

Line 373 uses the deprecated softprops/action-gh-release@v1 action. Upgrade to v2 or later to align with the fixes needed in .github/workflows/linux_packages.yaml.

  - name: Upload package to release
    if: github.event_name == 'release'
-   uses: softprops/action-gh-release@v1
+   uses: softprops/action-gh-release@v2
    with:
      files: ${{ steps.find-pkg.outputs.pkg_path }}
.github/workflows/linux_packages_rpm.yaml (2)

116-120: Verify setup_protoc action has required metadata fields.

The past review flagged that ./.github/actions/setup_protoc/action.yaml is missing required top-level name and description fields. This is still reported by actionlint and will prevent the workflow from running. Ensure the action's action.yaml file includes:

name: "Setup Protocol Buffers Compiler"
description: "Sets up the Protocol Buffers compiler (protoc) with caching support"

294-300: Update softprops/action-gh-release to v2.

The past review flagged that softprops/action-gh-release@v1 is deprecated and too old to run on current GitHub Actions. This is still reported by actionlint. Upgrade to v2 and verify compatibility:

- uses: softprops/action-gh-release@v1
+ uses: softprops/action-gh-release@v2

Consult the v2 release documentation to confirm input/output compatibility, as the action's interface may have changed.

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between bf171ce and c5b53f0.

📒 Files selected for processing (3)
  • .github/workflows/linux_packages.yaml (1 hunks)
  • .github/workflows/linux_packages_arch.yaml (1 hunks)
  • .github/workflows/linux_packages_rpm.yaml (1 hunks)
🧰 Additional context used
🪛 actionlint (1.7.8)
.github/workflows/linux_packages_arch.yaml

373-373: the runner of "softprops/action-gh-release@v1" action is too old to run on GitHub Actions. update the action's version to fix this issue

(action)

.github/workflows/linux_packages_rpm.yaml

117-117: name is required in action metadata "/home/jailuser/git/.github/actions/setup_protoc/action.yaml"

(action)


117-117: description is required in metadata of "" action at "/home/jailuser/git/.github/actions/setup_protoc/action.yaml"

(action)


296-296: the runner of "softprops/action-gh-release@v1" action is too old to run on GitHub Actions. update the action's version to fix this issue

(action)

.github/workflows/linux_packages.yaml

285-285: the runner of "softprops/action-gh-release@v1" action is too old to run on GitHub Actions. update the action's version to fix this issue

(action)


303-303: label "ubuntu-20.04" is unknown. available labels are "windows-latest", "windows-latest-8-cores", "windows-2025", "windows-2022", "windows-11-arm", "ubuntu-latest", "ubuntu-latest-4-cores", "ubuntu-latest-8-cores", "ubuntu-latest-16-cores", "ubuntu-24.04", "ubuntu-24.04-arm", "ubuntu-22.04", "ubuntu-22.04-arm", "macos-latest", "macos-latest-xl", "macos-latest-xlarge", "macos-latest-large", "macos-26-xlarge", "macos-26", "macos-15-intel", "macos-15-xlarge", "macos-15-large", "macos-15", "macos-14-xl", "macos-14-xlarge", "macos-14-large", "macos-14", "macos-13-xl", "macos-13-xlarge", "macos-13-large", "macos-13", "self-hosted", "x64", "arm", "arm64", "linux", "macos", "windows". if it is a custom label for self-hosted runner, set list of labels in actionlint.yaml config file

(runner-label)


307-307: label "ubuntu-20.04" is unknown. available labels are "windows-latest", "windows-latest-8-cores", "windows-2025", "windows-2022", "windows-11-arm", "ubuntu-latest", "ubuntu-latest-4-cores", "ubuntu-latest-8-cores", "ubuntu-latest-16-cores", "ubuntu-24.04", "ubuntu-24.04-arm", "ubuntu-22.04", "ubuntu-22.04-arm", "macos-latest", "macos-latest-xl", "macos-latest-xlarge", "macos-latest-large", "macos-26-xlarge", "macos-26", "macos-15-intel", "macos-15-xlarge", "macos-15-large", "macos-15", "macos-14-xl", "macos-14-xlarge", "macos-14-large", "macos-14", "macos-13-xl", "macos-13-xlarge", "macos-13-large", "macos-13", "self-hosted", "x64", "arm", "arm64", "linux", "macos", "windows". if it is a custom label for self-hosted runner, set list of labels in actionlint.yaml config file

(runner-label)


387-387: name is required in action metadata "/home/jailuser/git/.github/actions/setup_protoc/action.yaml"

(action)


387-387: description is required in metadata of "" action at "/home/jailuser/git/.github/actions/setup_protoc/action.yaml"

(action)


400-400: name is required in action metadata "/home/jailuser/git/.github/actions/pnpm_install/action.yaml"

(action)


400-400: description is required in metadata of "" action at "/home/jailuser/git/.github/actions/pnpm_install/action.yaml"

(action)


403-403: name is required in action metadata "/home/jailuser/git/.github/actions/poetry_install/action.yaml"

(action)


403-403: description is required in metadata of "" action at "/home/jailuser/git/.github/actions/poetry_install/action.yaml"

(action)


569-569: the runner of "softprops/action-gh-release@v1" action is too old to run on GitHub Actions. update the action's version to fix this issue

(action)

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: build-rpm (x86_64-unknown-linux-gnu, x86_64, stt-openblas,llm-vulkan, ubuntu-24.04, 40)
  • GitHub Check: build-arch-package (x86_64-unknown-linux-gnu, x86_64, stt-openblas,llm-vulkan, linux/amd64)
🔇 Additional comments (4)
.github/workflows/linux_packages_arch.yaml (1)

41-46: Address ARM64 support TODO.

Lines 41–46 disable ARM64 builds with a TODO. While this is a reasonable temporary measure, clarify the technical blocker (comment notes archlinux:latest doesn't support ARM64) and whether an alternative approach (e.g., using a custom cross-compilation container) is planned for a follow-up PR.

Can you confirm whether this limitation is expected to be resolved in a near-term follow-up, or if ARM64 support for Arch packaging should be deferred?

.github/workflows/linux_packages_rpm.yaml (3)

23-26: TAURI_CONF_PATH correctly includes apps/desktop/ prefix.

The environment variables are properly configured. Line 25 now correctly references the monorepo structure with apps/desktop/src-tauri/tauri.conf.{stable,nightly}.json, aligning with the artifact discovery in line 192 and the build context noted in lines 171–172.


160-178: Cross-compilation and build configuration is well-structured.

The ARM64 environment variables (lines 160–166) are correctly configured. The basename extraction (line 173) and path re-mapping in the Tauri build command properly account for the pnpm execution context running from apps/desktop/, as explained in the inline comment. Build flags and secrets are appropriately configured.


189-286: RPM discovery, testing, and verification logic is robust.

The RPM discovery (lines 189–200) safely uses find | head -n 1 within the matrix context. The x86_64 installation test (lines 201–240) comprehensively verifies binary presence, executability, and .desktop file integration. The ARM64 verification (lines 241–286) appropriately handles cross-compiled artifacts by extracting and inspecting RPM contents rather than attempting installation. Error handling and cleanup are thorough throughout.


- name: Upload .deb to release
if: github.event_name == 'release'
uses: softprops/action-gh-release@v1
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Upgrade deprecated GitHub Actions version — softprops/action-gh-release@v1.

Lines 285 and 569 use the deprecated softprops/action-gh-release@v1 action. Upgrade both to v2 or later.

  - name: Upload .deb to release
    if: github.event_name == 'release'
-   uses: softprops/action-gh-release@v1
+   uses: softprops/action-gh-release@v2
    with:
      files: ${{ steps.find-deb.outputs.deb_path }}

  - name: Upload AppImage to release
    if: github.event_name == 'release'
-   uses: softprops/action-gh-release@v1
+   uses: softprops/action-gh-release@v2
    with:
      files: ${{ steps.find-appimage.outputs.appimage_path }}

Also applies to: 569-569

🧰 Tools
🪛 actionlint (1.7.8)

285-285: the runner of "softprops/action-gh-release@v1" action is too old to run on GitHub Actions. update the action's version to fix this issue

(action)

🤖 Prompt for AI Agents
.github/workflows/linux_packages.yaml around lines 285 and 569: the workflow
uses the deprecated softprops/action-gh-release@v1; update both occurrences to
softprops/action-gh-release@v2 (or a later stable major) and adjust any action
inputs if v2 changed names/required fields, then run the workflow locally or in
CI to verify the release step still behaves correctly.

- target: "x86_64-unknown-linux-gnu"
arch: "x86_64"
features: "stt-openblas,llm-vulkan"
runner: "ubuntu-20.04"
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

Fix deprecated runner labels — ubuntu-20.04 no longer available on GitHub Actions.

Lines 303 and 307 specify runner: "ubuntu-20.04", which is deprecated and will cause immediate workflow failure. Update both occurrences to ubuntu-24.04 (consistent with the Debian build job at line 40).

  - target: "x86_64-unknown-linux-gnu"
    arch: "x86_64"
    features: "stt-openblas,llm-vulkan"
-   runner: "ubuntu-20.04"
+   runner: "ubuntu-24.04"
  - target: "aarch64-unknown-linux-gnu"
    arch: "aarch64"
    features: "stt-openblas,llm-vulkan"
-   runner: "ubuntu-20.04"
+   runner: "ubuntu-24.04"

Also applies to: 307-307

🧰 Tools
🪛 actionlint (1.7.8)

303-303: label "ubuntu-20.04" is unknown. available labels are "windows-latest", "windows-latest-8-cores", "windows-2025", "windows-2022", "windows-11-arm", "ubuntu-latest", "ubuntu-latest-4-cores", "ubuntu-latest-8-cores", "ubuntu-latest-16-cores", "ubuntu-24.04", "ubuntu-24.04-arm", "ubuntu-22.04", "ubuntu-22.04-arm", "macos-latest", "macos-latest-xl", "macos-latest-xlarge", "macos-latest-large", "macos-26-xlarge", "macos-26", "macos-15-intel", "macos-15-xlarge", "macos-15-large", "macos-15", "macos-14-xl", "macos-14-xlarge", "macos-14-large", "macos-14", "macos-13-xl", "macos-13-xlarge", "macos-13-large", "macos-13", "self-hosted", "x64", "arm", "arm64", "linux", "macos", "windows". if it is a custom label for self-hosted runner, set list of labels in actionlint.yaml config file

(runner-label)

🤖 Prompt for AI Agents
.github/workflows/linux_packages.yaml around lines 303 and 307: the workflow
uses the deprecated runner "ubuntu-20.04" which will fail; update both
occurrences to "ubuntu-24.04" to match the supported GitHub Actions runners (and
remain consistent with the Debian build job at line 40).

The Arch workflow only needs the binary to create the .pkg.tar.zst package.
AppImage bundling fails due to old strip utility not recognizing modern
.relr.dyn sections in Arch libraries, but this doesn't affect the Arch
package creation.
- Fix RPM test script to correctly detect package name (hyprnote-nightly vs hyprnote)
- Fix Debian test script to correctly detect package name
- Update binary path detection to use '/usr/bin/' instead of 'bin/.*' pattern
- Add package contents debugging output on binary detection failure
- Disable ARM64 builds temporarily in all workflows due to cross-compilation dependency issues
- This ensures all x86_64 builds and tests complete successfully
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

♻️ Duplicate comments (1)
.github/workflows/linux_packages_rpm.yaml (1)

303-305: Upgrade softprops/action-gh-release from v1 to v2.

v1 has been deprecated for over a year and might not work on current GitHub Actions runners due to enforcing Node 20. The latest v2.3.2 is actively maintained and the files input remains compatible.

  - name: Upload RPM to release
    if: github.event_name == 'release'
-   uses: softprops/action-gh-release@v1
+   uses: softprops/action-gh-release@v2
    with:
      files: ${{ steps.find-rpm.outputs.rpm_path }}
📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between f7e2a87 and 67f3661.

📒 Files selected for processing (2)
  • .github/workflows/linux_packages.yaml (1 hunks)
  • .github/workflows/linux_packages_rpm.yaml (1 hunks)
🧰 Additional context used
🪛 actionlint (1.7.8)
.github/workflows/linux_packages.yaml

132-132: name is required in action metadata "/home/jailuser/git/.github/actions/setup_protoc/action.yaml"

(action)


132-132: description is required in metadata of "" action at "/home/jailuser/git/.github/actions/setup_protoc/action.yaml"

(action)


145-145: name is required in action metadata "/home/jailuser/git/.github/actions/pnpm_install/action.yaml"

(action)


145-145: description is required in metadata of "" action at "/home/jailuser/git/.github/actions/pnpm_install/action.yaml"

(action)


148-148: name is required in action metadata "/home/jailuser/git/.github/actions/poetry_install/action.yaml"

(action)


148-148: description is required in metadata of "" action at "/home/jailuser/git/.github/actions/poetry_install/action.yaml"

(action)


292-292: the runner of "softprops/action-gh-release@v1" action is too old to run on GitHub Actions. update the action's version to fix this issue

(action)


310-310: label "ubuntu-20.04" is unknown. available labels are "windows-latest", "windows-latest-8-cores", "windows-2025", "windows-2022", "windows-11-arm", "ubuntu-latest", "ubuntu-latest-4-cores", "ubuntu-latest-8-cores", "ubuntu-latest-16-cores", "ubuntu-24.04", "ubuntu-24.04-arm", "ubuntu-22.04", "ubuntu-22.04-arm", "macos-latest", "macos-latest-xl", "macos-latest-xlarge", "macos-latest-large", "macos-26-xlarge", "macos-26", "macos-15-intel", "macos-15-xlarge", "macos-15-large", "macos-15", "macos-14-xl", "macos-14-xlarge", "macos-14-large", "macos-14", "macos-13-xl", "macos-13-xlarge", "macos-13-large", "macos-13", "self-hosted", "x64", "arm", "arm64", "linux", "macos", "windows". if it is a custom label for self-hosted runner, set list of labels in actionlint.yaml config file

(runner-label)


578-578: the runner of "softprops/action-gh-release@v1" action is too old to run on GitHub Actions. update the action's version to fix this issue

(action)

.github/workflows/linux_packages_rpm.yaml

118-118: name is required in action metadata "/home/jailuser/git/.github/actions/setup_protoc/action.yaml"

(action)


118-118: description is required in metadata of "" action at "/home/jailuser/git/.github/actions/setup_protoc/action.yaml"

(action)


303-303: the runner of "softprops/action-gh-release@v1" action is too old to run on GitHub Actions. update the action's version to fix this issue

(action)

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: build-linux-packages (x86_64-unknown-linux-gnu, amd64, stt-openblas,llm-vulkan, ubuntu-24.04)
  • GitHub Check: build-rpm (x86_64-unknown-linux-gnu, x86_64, stt-openblas,llm-vulkan, ubuntu-24.04, 40)
🔇 Additional comments (2)
.github/workflows/linux_packages.yaml (2)

292-296: Upgrade softprops/action-gh-release from v1 to v2.

The v1 action is effectively deprecated, with users reporting deprecation/Node.js-16 warnings when using @v1. v2 is the current recommended version and supports the files input parameter your workflow uses.

  - name: Upload .deb to release
    if: github.event_name == 'release'
-   uses: softprops/action-gh-release@v1
+   uses: softprops/action-gh-release@v2
    with:
      files: ${{ steps.find-deb.outputs.deb_path }}

578-582: Upgrade to v2 requires testing due to matrix build implications.

v1 is confirmed deprecated and triggers deprecation warnings, and v2 is the current published major version. However, this workflow uses matrix builds where multiple jobs upload to the same release concurrently. v2 has known breaking changes in release creation/update semantics, and there are reported regressions with "already_exists" errors when relying on incremental matrix uploads.

Before upgrading, verify:

  • Test with matrix builds uploading to the same release
  • Check for "already_exists" or unexpected behavior changes
  • Consider pinning to a specific v2.x patch after testing
  - name: Upload AppImage to release
    if: github.event_name == 'release'
-   uses: softprops/action-gh-release@v1
+   uses: softprops/action-gh-release@v2
    with:
      files: ${{ steps.find-appimage.outputs.appimage_path }}

Comment on lines +118 to +120
uses: ./.github/actions/setup_protoc
with:
repo-token: ${{ secrets.GITHUB_TOKEN }}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

Add required metadata to .github/actions/setup_protoc/action.yaml.

The custom action is missing required name and description metadata fields, which GitHub Actions requires for composite actions. Add these fields at the top level of the action.yaml file.

name: "Setup Protocol Buffers Compiler"
description: "Sets up the Protocol Buffers compiler (protoc) with caching support"
inputs:
  repo-token:
    # ... rest of inputs


---

🏁 Script executed:

```shell
#!/bin/bash
# Locate and display the setup_protoc action.yaml file
fd -t f "action.yaml" -o -t f "action.yml" | grep setup_protoc

# If found, display its contents
if [ -f ".github/actions/setup_protoc/action.yaml" ]; then
  echo "=== Contents of .github/actions/setup_protoc/action.yaml ==="
  cat .github/actions/setup_protoc/action.yaml
elif [ -f ".github/actions/setup_protoc/action.yml" ]; then
  echo "=== Contents of .github/actions/setup_protoc/action.yml ==="
  cat .github/actions/setup_protoc/action.yml
else
  echo "=== Searching for action files in .github/actions ==="
  find .github/actions -name "action.*" -type f
fi

Length of output: 525



---

🌐 Web query:

```web
GitHub Actions composite action name description required metadata

💡 Result:

Short answer — required metadata for a composite action (action.yml / action.yaml):

  • name: Required. The action display name. [1]
  • description: Required. Short summary of the action. [1]
  • runs: Required. Must include using: "composite" and runs.steps (the steps to execute). runs.using must equal "composite". [1][2]

Optional but common: author, inputs, outputs, branding. [1][2]

Sources: GitHub Docs — Metadata syntax reference and Creating a composite action. [1][2]


Add required name and description fields to .github/actions/setup_protoc/action.yaml.

GitHub Actions requires name and description as mandatory metadata fields for composite actions. The current action.yaml is missing both. Add them at the top level before the inputs section:

name: "Setup Protocol Buffers Compiler"
description: "Sets up the Protocol Buffers compiler (protoc) with caching support"
inputs:
  repo-token:
    required: true
    type: string
🧰 Tools
🪛 actionlint (1.7.8)

118-118: name is required in action metadata "/home/jailuser/git/.github/actions/setup_protoc/action.yaml"

(action)


118-118: description is required in metadata of "" action at "/home/jailuser/git/.github/actions/setup_protoc/action.yaml"

(action)

🤖 Prompt for AI Agents
In .github/workflows/linux_packages_rpm.yaml around lines 118-120, the
referenced composite action .github/actions/setup_protoc/action.yaml is missing
mandatory top-level metadata; open that action.yaml and add a top-level name
field set to "Setup Protocol Buffers Compiler" and a top-level description field
set to "Sets up the Protocol Buffers compiler (protoc) with caching support"
placed before the inputs section, ensuring the existing inputs (e.g.,
repo-token) remain and are declared as required with type: string.

Comment on lines +132 to +135
uses: ./.github/actions/setup_protoc
with:
repo-token: ${{ secrets.GITHUB_TOKEN }}

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

Add required metadata to three custom action files.

The following custom actions are missing required name and description metadata fields, which GitHub Actions requires for composite actions:

  • .github/actions/setup_protoc/action.yaml
  • .github/actions/pnpm_install/action.yaml
  • .github/actions/poetry_install/action.yaml

Add these fields at the top level of each action.yaml file.

Example for setup_protoc:

name: "Setup Protocol Buffers Compiler"
description: "Sets up the Protocol Buffers compiler (protoc) with caching support"
inputs:
  repo-token:
    # ... rest of inputs

Apply the same pattern to pnpm_install and poetry_install, using appropriate names and descriptions for each.

Also applies to: 145-145, 148-148


I need to verify the review comment by checking the actual content of the custom action files. Let me inspect them.


🏁 Script executed:

#!/bin/bash
# Check if the three action files exist and inspect their content

echo "=== Checking setup_protoc/action.yaml ==="
if [ -f ".github/actions/setup_protoc/action.yaml" ]; then
  cat ".github/actions/setup_protoc/action.yaml"
else
  echo "File not found"
fi

echo -e "\n=== Checking pnpm_install/action.yaml ==="
if [ -f ".github/actions/pnpm_install/action.yaml" ]; then
  cat ".github/actions/pnpm_install/action.yaml"
else
  echo "File not found"
fi

echo -e "\n=== Checking poetry_install/action.yaml ==="
if [ -f ".github/actions/poetry_install/action.yaml" ]; then
  cat ".github/actions/poetry_install/action.yaml"
else
  echo "File not found"
fi

Length of output: 1142


Add required metadata to three custom action files.

The following custom actions are missing required name and description metadata fields, which GitHub Actions requires for composite actions:

  • .github/actions/setup_protoc/action.yaml
  • .github/actions/pnpm_install/action.yaml
  • .github/actions/poetry_install/action.yaml

Add these fields at the top level of each action.yaml file, before the inputs or runs sections.

Example for setup_protoc:

name: "Setup Protocol Buffers Compiler"
description: "Sets up the Protocol Buffers compiler (protoc) with caching support"
inputs:
  repo-token:
    required: true
    type: string

Apply the same pattern to pnpm_install and poetry_install, using appropriate names and descriptions for each.

🧰 Tools
🪛 actionlint (1.7.8)

132-132: name is required in action metadata "/home/jailuser/git/.github/actions/setup_protoc/action.yaml"

(action)


132-132: description is required in metadata of "" action at "/home/jailuser/git/.github/actions/setup_protoc/action.yaml"

(action)

🤖 Prompt for AI Agents
In .github/workflows/linux_packages.yaml around lines 132-135, three referenced
composite action files (.github/actions/setup_protoc/action.yaml,
.github/actions/pnpm_install/action.yaml,
.github/actions/poetry_install/action.yaml) are missing required top-level name
and description fields; open each action.yaml and add a top-level name and
description entry before the inputs or runs sections (for example for
setup_protoc use a name like "Setup Protocol Buffers Compiler" and a description
like "Sets up the Protocol Buffers compiler (protoc) with caching support"; for
pnpm_install use a name like "Install dependencies with pnpm" and a description
like "Installs project dependencies using pnpm with optional cache support"; for
poetry_install use a name like "Install dependencies with Poetry" and a
description like "Installs Python dependencies using Poetry and manages
virtualenvs"), ensuring fields are plain strings and placed at the top level of
each action.yaml.

Comment on lines 310 to 315
runner: "ubuntu-20.04"
# ARM64 builds disabled temporarily due to cross-compilation dependency issues
# - target: "aarch64-unknown-linux-gnu"
# arch: "aarch64"
# features: "stt-openblas,llm-vulkan"
# runner: "ubuntu-20.04"
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

Update deprecated runner label ubuntu-20.04 to ubuntu-24.04.

The ubuntu-20.04 runner label is no longer available on GitHub Actions and will cause the AppImage build job to fail. Update to a supported label.

  - target: "x86_64-unknown-linux-gnu"
    arch: "x86_64"
    features: "stt-openblas,llm-vulkan"
-   runner: "ubuntu-20.04"
  # ARM64 builds disabled temporarily due to cross-compilation dependency issues
  # - target: "aarch64-unknown-linux-gnu"
  #   arch: "aarch64"
  #   features: "stt-openblas,llm-vulkan"
-   runner: "ubuntu-20.04"
+   runner: "ubuntu-24.04"

Alternatively, if ubuntu-20.04 was chosen for older GLIBC compatibility, use ubuntu-22.04 as a middle ground.


🌐 Web query:

GitHub Actions Ubuntu runner labels available 2025

💡 Result:

Current (2025) GitHub-hosted Ubuntu runner labels

  • ubuntu-latest — maps to Ubuntu 24.04 (default). [1][2]
  • ubuntu-24.04 — explicit 24.04 image. [1][3]
  • ubuntu-22.04 — explicit 22.04 image. [1]
  • ubuntu-20.04 — explicit 20.04 image (being retired; scheduled full retirement April 15, 2025). [2]
  • ubuntu-24.04-arm — Ubuntu 24.04 arm64 image. [1]
  • ubuntu-22.04-arm — Ubuntu 22.04 arm64 image. [1]

Sources:
[1] GitHub Docs — Choosing the runner for a job (available GitHub-hosted runner labels).
[2] GitHub Blog changelog — migration of ubuntu-latest to 24.04 and Ubuntu 20.04 retirement notice.
[3] actions/runner-images release log — Ubuntu 24.04 runner image (ubuntu-latest → 24.04 rollout).


🌐 Web query:

ubuntu-20.04 GitHub Actions runner deprecated

💡 Result:

Short answer: GitHub began deprecating the ubuntu-20.04 hosted runner on Feb 1, 2025 and planned full unsupported/retirement in April 2025 (target updated to April 15, 2025). Migrate workflows to ubuntu-22.04, ubuntu-24.04, or ubuntu-latest. [1][2]

Sources:

  • actions/runner-images deprecation announcement (ubuntu-20.04 deprecation begins 2025-02-01; fully unsupported target 2025-04-15). [1]
  • GitHub-hosted runners reference — use ubuntu-latest / ubuntu-22.04 / ubuntu-24.04. [2]

🌐 Web query:

GitHub Actions runner images ubuntu-24.04 ubuntu-22.04 supported

💡 Result:

Short answer: Yes — both ubuntu-24.04 and ubuntu-22.04 are supported GitHub-hosted runner images. ubuntu-24.04 is available (GA) and is one of the labels you can use (along with ubuntu-22.04 and ubuntu-latest); arm64 variants (ubuntu-24.04-arm / ubuntu-22.04-arm) are also provided. [1][2][3]

Sources:

  • GitHub-hosted runners reference (lists ubuntu-24.04 and ubuntu-22.04). [1]
  • GitHub Changelog announcing Ubuntu 24.04 GA and ubuntu-latest migration. [2]
  • actions/runner-images repo (available images and labels, plus arm variants). [3]

Update deprecated runner label ubuntu-20.04 to ubuntu-24.04.

The ubuntu-20.04 runner is no longer available—it was retired April 15, 2025. This will cause the AppImage build job to fail. Update to ubuntu-24.04 or ubuntu-22.04, both of which are currently supported.

  - target: "x86_64-unknown-linux-gnu"
    arch: "x86_64"
    features: "stt-openblas,llm-vulkan"
-   runner: "ubuntu-20.04"
+   runner: "ubuntu-24.04"
  # ARM64 builds disabled temporarily due to cross-compilation dependency issues
  # - target: "aarch64-unknown-linux-gnu"
  #   arch: "aarch64"
  #   features: "stt-openblas,llm-vulkan"
-   runner: "ubuntu-20.04"
+   runner: "ubuntu-24.04"

Update both instances (line 310 and the commented-out ARM64 section at line 315) to prevent future failures if ARM64 builds are re-enabled.

Committable suggestion skipped: line range outside the PR's diff.

🧰 Tools
🪛 actionlint (1.7.8)

310-310: label "ubuntu-20.04" is unknown. available labels are "windows-latest", "windows-latest-8-cores", "windows-2025", "windows-2022", "windows-11-arm", "ubuntu-latest", "ubuntu-latest-4-cores", "ubuntu-latest-8-cores", "ubuntu-latest-16-cores", "ubuntu-24.04", "ubuntu-24.04-arm", "ubuntu-22.04", "ubuntu-22.04-arm", "macos-latest", "macos-latest-xl", "macos-latest-xlarge", "macos-latest-large", "macos-26-xlarge", "macos-26", "macos-15-intel", "macos-15-xlarge", "macos-15-large", "macos-15", "macos-14-xl", "macos-14-xlarge", "macos-14-large", "macos-14", "macos-13-xl", "macos-13-xlarge", "macos-13-large", "macos-13", "self-hosted", "x64", "arm", "arm64", "linux", "macos", "windows". if it is a custom label for self-hosted runner, set list of labels in actionlint.yaml config file

(runner-label)

🤖 Prompt for AI Agents
.github/workflows/linux_packages.yaml lines 310-315: the workflow uses the
deprecated runner label "ubuntu-20.04" which was retired; update the runner
value to "ubuntu-24.04" in the active job and also update the commented ARM64
block so that the commented lines reference "ubuntu-24.04" (or "ubuntu-22.04" if
you prefer) to prevent future failures when re-enabling ARM64 builds; keep the
rest of the block unchanged.

The previous attempt used '|| echo' but this didn't work because the
script runs with 'set -e' which exits immediately on any error.

This fix:
- Temporarily disables 'set -e' during the Tauri build
- Captures the exit code
- Re-enables 'set -e'
- Checks if the build failed, and if so, verifies the binary was still
  built (which is all we need for the Arch package)
- Provides clear messaging about expected AppImage bundling failures
- Only exits with error if the binary itself wasn't built

The AppImage bundling fails on modern Arch due to incompatible strip
utility, but we only need the binary for creating the .pkg.tar.zst
package.
The previous approach tried to handle AppImage bundling failures, but
the failure occurs during the Tauri build process before the binary
compilation completes.

This fix uses --bundles none to skip all bundling (AppImage, deb, rpm)
and only build the binary. This is perfect for Arch since we create our
own .pkg.tar.zst package from the binary.

This avoids the strip incompatibility issue with modern Arch libraries
that have .relr.dyn sections.
The --bundles flag doesn't accept 'none' as a value. Instead of using
Tauri CLI (which always tries to create bundles), we now build with
cargo directly. This gives us just the binary, which is all we need
for creating the .pkg.tar.zst Arch package.

Changes:
- Build with cargo instead of Tauri CLI
- Pass FEATURES environment variable to Docker container
- Verify binary is built at expected location
- Skip all bundling steps (AppImage/deb/rpm)
The package filename contains spaces (e.g., 'Hyprnote Nightly_0.0.63_amd64.deb')
which causes dpkg to fail when the path is not quoted.

This fix adds quotes around the deb_path output variable in the
installation command.
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

♻️ Duplicate comments (4)
.github/workflows/linux_packages.yaml (3)

310-310: Fix deprecated runner label at line 310 — ubuntu-20.04 was retired April 15, 2025.

The AppImage build matrix still references the deprecated ubuntu-20.04 runner, which will cause immediate workflow failure. Update to ubuntu-24.04 to match the build-linux-packages job at line 40.

          - target: "x86_64-unknown-linux-gnu"
            arch: "x86_64"
            features: "stt-openblas,llm-vulkan"
-           runner: "ubuntu-20.04"
+           runner: "ubuntu-24.04"

Also update the commented ARM64 section at line 315 so it's ready if ARM64 builds are re-enabled in the future.


292-292: Upgrade deprecated softprops/action-gh-release from v1 to v2.

Both release upload steps (lines 292 and 578) use the outdated softprops/action-gh-release@v1, which actionlint flags as incompatible with current GitHub Actions. Upgrade both to v2:

  - name: Upload .deb to release
    if: github.event_name == 'release'
-   uses: softprops/action-gh-release@v1
+   uses: softprops/action-gh-release@v2
    with:
      files: ${{ steps.find-deb.outputs.deb_path }}

  - name: Upload AppImage to release
    if: github.event_name == 'release'
-   uses: softprops/action-gh-release@v1
+   uses: softprops/action-gh-release@v2
    with:
      files: ${{ steps.find-appimage.outputs.appimage_path }}

Also applies to: 578-578


132-132: Add required metadata to custom action files.

Lines 132, 145, and 148 reference custom actions that are missing required name and description fields per GitHub Actions specifications. Actionlint flags all three:

  • .github/actions/setup_protoc/action.yaml (line 132)
  • .github/actions/pnpm_install/action.yaml (line 145)
  • .github/actions/poetry_install/action.yaml (line 148)

Each action.yaml file must include top-level name and description fields. Example for setup_protoc:

name: Setup Protocol Buffers Compiler
description: Installs Protocol Buffers compiler (protoc) with caching support
inputs:
  repo-token:
    required: true
    type: string
runs:
  ...

Apply the same pattern to pnpm_install and poetry_install with appropriate names and descriptions.

Also applies to: 145-145, 148-148

.github/workflows/linux_packages_arch.yaml (1)

406-406: Upgrade deprecated softprops/action-gh-release from v1 to v2.

Line 406 uses the outdated softprops/action-gh-release@v1, which actionlint flags as incompatible with current GitHub Actions. Upgrade to v2:

  - name: Upload package to release
    if: github.event_name == 'release'
-   uses: softprops/action-gh-release@v1
+   uses: softprops/action-gh-release@v2
    with:
      files: ${{ steps.find-pkg.outputs.pkg_path }}
🧹 Nitpick comments (1)
CLAUDE.md (1)

68-70: Reduce repetitive sentence starters in the "Do Not" section.

Three consecutive sentences begin with "Do not," which reduces readability. Vary the phrasing for better flow.

Apply this diff to improve readability:

-## Do Not
-- Do not commit large model binaries.
-- Do not add new formatters or global toolchains without discussion.
-- Do not enable heavy features for simple type export or CI smoke tests.
+## Do Not
+- Avoid committing large model binaries.
+- Do not add new formatters or global toolchains without discussion.
+- Heavy features should not be enabled for simple type export or CI smoke tests.
📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 8bf8d8c and a0720c7.

📒 Files selected for processing (3)
  • .github/workflows/linux_packages.yaml (1 hunks)
  • .github/workflows/linux_packages_arch.yaml (1 hunks)
  • CLAUDE.md (1 hunks)
🧰 Additional context used
🪛 actionlint (1.7.8)
.github/workflows/linux_packages_arch.yaml

406-406: the runner of "softprops/action-gh-release@v1" action is too old to run on GitHub Actions. update the action's version to fix this issue

(action)

.github/workflows/linux_packages.yaml

132-132: name is required in action metadata "/home/jailuser/git/.github/actions/setup_protoc/action.yaml"

(action)


132-132: description is required in metadata of "" action at "/home/jailuser/git/.github/actions/setup_protoc/action.yaml"

(action)


145-145: name is required in action metadata "/home/jailuser/git/.github/actions/pnpm_install/action.yaml"

(action)


145-145: description is required in metadata of "" action at "/home/jailuser/git/.github/actions/pnpm_install/action.yaml"

(action)


148-148: name is required in action metadata "/home/jailuser/git/.github/actions/poetry_install/action.yaml"

(action)


148-148: description is required in metadata of "" action at "/home/jailuser/git/.github/actions/poetry_install/action.yaml"

(action)


292-292: the runner of "softprops/action-gh-release@v1" action is too old to run on GitHub Actions. update the action's version to fix this issue

(action)


310-310: label "ubuntu-20.04" is unknown. available labels are "windows-latest", "windows-latest-8-cores", "windows-2025", "windows-2022", "windows-11-arm", "ubuntu-latest", "ubuntu-latest-4-cores", "ubuntu-latest-8-cores", "ubuntu-latest-16-cores", "ubuntu-24.04", "ubuntu-24.04-arm", "ubuntu-22.04", "ubuntu-22.04-arm", "macos-latest", "macos-latest-xl", "macos-latest-xlarge", "macos-latest-large", "macos-26-xlarge", "macos-26", "macos-15-intel", "macos-15-xlarge", "macos-15-large", "macos-15", "macos-14-xl", "macos-14-xlarge", "macos-14-large", "macos-14", "macos-13-xl", "macos-13-xlarge", "macos-13-large", "macos-13", "self-hosted", "x64", "arm", "arm64", "linux", "macos", "windows". if it is a custom label for self-hosted runner, set list of labels in actionlint.yaml config file

(runner-label)


578-578: the runner of "softprops/action-gh-release@v1" action is too old to run on GitHub Actions. update the action's version to fix this issue

(action)

🪛 LanguageTool
CLAUDE.md

[style] ~70-~70: Three successive sentences begin with the same word. Consider rewording the sentence or use a thesaurus to find a synonym.
Context: ...global toolchains without discussion. - Do not enable heavy features for simple ty...

(ENGLISH_WORD_REPEAT_BEGINNING_RULE)

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: build-linux-packages (x86_64-unknown-linux-gnu, amd64, stt-openblas,llm-vulkan, ubuntu-24.04)
  • GitHub Check: build-arch-package (x86_64-unknown-linux-gnu, x86_64, stt-openblas,llm-vulkan, linux/amd64)
🔇 Additional comments (1)
CLAUDE.md (1)

1-70: Comprehensive and actionable contributor guidance for a complex polyglot monorepo.

This document provides clear, prescriptive guidance across all major development workflows: builds, testing, formatting, i18n, Rust conventions, feature addition, TypeScript apps, and critical "do not" patterns. The structure is well-suited for both human and AI agent consumption, with specific commands and constraints that should reduce friction for new contributors and support the broader Linux support initiative by codifying expectations upfront.

The Cargo package is named 'desktop', not 'hyprnote', so the compiled
binary is named 'desktop'. Updated the workflow to:
- Look for the 'desktop' binary after cargo build
- Rename it to 'hyprnote' during package installation

This fixes the binary not found error in the Arch Linux packaging.
Changed from ubuntu-20.04 to ubuntu-22.04 for the AppImage build job.
While ubuntu-20.04 offers better compatibility, ubuntu-22.04 runners
have better availability on GitHub Actions, reducing queue times.
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

♻️ Duplicate comments (2)
.github/workflows/linux_packages.yaml (2)

576-582: Upgrade deprecated softprops/action-gh-release@v1 to v2.

Line 578 uses the deprecated softprops/action-gh-release@v1, which is no longer supported on GitHub Actions. Upgrade to v2 (or later stable major version).

  - name: Upload AppImage to release
    if: github.event_name == 'release'
-   uses: softprops/action-gh-release@v1
+   uses: softprops/action-gh-release@v2
    with:
      files: ${{ steps.find-appimage.outputs.appimage_path }}

290-296: Upgrade deprecated softprops/action-gh-release@v1 to v2.

Line 292 uses the deprecated softprops/action-gh-release@v1, which is no longer supported on GitHub Actions. Upgrade to v2 (or later stable major version).

  - name: Upload .deb to release
    if: github.event_name == 'release'
-   uses: softprops/action-gh-release@v1
+   uses: softprops/action-gh-release@v2
    with:
      files: ${{ steps.find-deb.outputs.deb_path }}
🧹 Nitpick comments (1)
.github/workflows/linux_packages.yaml (1)

310-315: Update commented ARM64 section to use supported runner.

While the ARM64 build is currently disabled, the commented section at line 315 references the deprecated ubuntu-20.04 runner (retired April 15, 2025). If ARM64 builds are re-enabled, this will cause immediate failure.

Update the commented section to use a supported runner for consistency and to prevent future issues:

  # ARM64 builds disabled temporarily due to cross-compilation dependency issues
  # - target: "aarch64-unknown-linux-gnu"
  #   arch: "aarch64"
  #   features: "stt-openblas,llm-vulkan"
-  #   runner: "ubuntu-20.04"
+  #   runner: "ubuntu-24.04"
📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 5c7791c and ad4735e.

📒 Files selected for processing (1)
  • .github/workflows/linux_packages.yaml (1 hunks)
🧰 Additional context used
🪛 actionlint (1.7.8)
.github/workflows/linux_packages.yaml

132-132: name is required in action metadata "/home/jailuser/git/.github/actions/setup_protoc/action.yaml"

(action)


132-132: description is required in metadata of "" action at "/home/jailuser/git/.github/actions/setup_protoc/action.yaml"

(action)


145-145: name is required in action metadata "/home/jailuser/git/.github/actions/pnpm_install/action.yaml"

(action)


145-145: description is required in metadata of "" action at "/home/jailuser/git/.github/actions/pnpm_install/action.yaml"

(action)


148-148: name is required in action metadata "/home/jailuser/git/.github/actions/poetry_install/action.yaml"

(action)


148-148: description is required in metadata of "" action at "/home/jailuser/git/.github/actions/poetry_install/action.yaml"

(action)


292-292: the runner of "softprops/action-gh-release@v1" action is too old to run on GitHub Actions. update the action's version to fix this issue

(action)


578-578: the runner of "softprops/action-gh-release@v1" action is too old to run on GitHub Actions. update the action's version to fix this issue

(action)

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: build-linux-packages (x86_64-unknown-linux-gnu, amd64, stt-openblas,llm-vulkan, ubuntu-24.04)
  • GitHub Check: build-appimage (x86_64-unknown-linux-gnu, x86_64, stt-openblas,llm-vulkan, ubuntu-22.04)
🔇 Additional comments (5)
.github/workflows/linux_packages.yaml (5)

1-26: Workflow structure and environment variables look good.

The TAURI_CONF_PATH correction from prior commits (with apps/desktop/ prefix) is correctly in place.


28-46: Job matrix and runner labels are correct.

The build-linux-packages job properly specifies ubuntu-24.04 which is currently supported.


159-282: Build, test, and verification steps for .deb package are well-structured.

The .deb packaging workflow includes proper:

  • Version validation
  • System dependency installation with ARM64 cross-compilation support
  • Comprehensive testing for x86_64 with actual package installation
  • Architecture-aware verification for cross-compiled ARM64 binaries

Testing approach with fallback handling is robust.


423-567: Build, test, and verification steps for AppImage are well-structured.

The AppImage packaging workflow includes proper:

  • Version validation
  • System dependency installation with ARM64 cross-compilation support
  • Comprehensive testing for x86_64 with AppImage extraction and inspection
  • Graceful fallback handling for ARM64 AppImage verification on x86_64 runners

Testing approach handles cross-platform limitations appropriately.


584-619: Flathub publishing scaffold is well-documented.

The disabled Flathub build includes clear documentation about prerequisites and enablement path for future use.

Ubuntu 22.04 needs libsoup-3.0-dev explicitly installed for Tauri v2.
While libwebkit2gtk-4.0-dev provides libsoup-2.4, Tauri requires the
newer libsoup-3.0 API.
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

♻️ Duplicate comments (3)
.github/workflows/linux_packages.yaml (3)

131-149: Duplicate issue: Custom actions still missing required metadata.

Static analysis continues to report that three custom actions are missing required name and description metadata fields:

  • Line 132: ./.github/actions/setup_protoc
  • Line 145: ./.github/actions/pnpm_install
  • Line 148: ./.github/actions/poetry_install

Each action.yaml file must include these top-level fields before the inputs or runs sections.

I can generate the required metadata for all three action files. Would you like me to create the updated action.yaml files with appropriate name and description fields for each action?


298-316: Update deprecated ubuntu-20.04 in commented-out ARM64 section to prevent future failures.

Line 315 in the commented-out ARM64 matrix references the deprecated ubuntu-20.04 runner, which was retired on April 15, 2025. When ARM64 builds are re-enabled, this will cause an immediate workflow failure. Update the commented section for consistency:

  # ARM64 builds disabled temporarily due to cross-compilation dependency issues
  # - target: "aarch64-unknown-linux-gnu"
  #   arch: "aarch64"
  #   features: "stt-openblas,llm-vulkan"
-  #   runner: "ubuntu-20.04"
+  #   runner: "ubuntu-24.04"

290-296: Upgrade deprecated softprops/action-gh-release@v1 to v2 at two locations.

Lines 292 and 581 use the deprecated v1 which will fail on GitHub Actions. Verification confirms v2 is compatible with the current files parameter format. Both instances need upgrading:

Line 292:

  - name: Upload .deb to release
    if: github.event_name == 'release'
-   uses: softprops/action-gh-release@v1
+   uses: softprops/action-gh-release@v2
    with:
      files: ${{ steps.find-deb.outputs.deb_path }}

Line 581:

  - name: Upload AppImage to release
    if: github.event_name == 'release'
-   uses: softprops/action-gh-release@v1
+   uses: softprops/action-gh-release@v2
    with:
      files: ${{ steps.find-appimage.outputs.appimage_path }}
📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between ad4735e and da37532.

📒 Files selected for processing (1)
  • .github/workflows/linux_packages.yaml (1 hunks)
🧰 Additional context used
🪛 actionlint (1.7.8)
.github/workflows/linux_packages.yaml

132-132: name is required in action metadata "/home/jailuser/git/.github/actions/setup_protoc/action.yaml"

(action)


132-132: description is required in metadata of "" action at "/home/jailuser/git/.github/actions/setup_protoc/action.yaml"

(action)


145-145: name is required in action metadata "/home/jailuser/git/.github/actions/pnpm_install/action.yaml"

(action)


145-145: description is required in metadata of "" action at "/home/jailuser/git/.github/actions/pnpm_install/action.yaml"

(action)


148-148: name is required in action metadata "/home/jailuser/git/.github/actions/poetry_install/action.yaml"

(action)


148-148: description is required in metadata of "" action at "/home/jailuser/git/.github/actions/poetry_install/action.yaml"

(action)


292-292: the runner of "softprops/action-gh-release@v1" action is too old to run on GitHub Actions. update the action's version to fix this issue

(action)


581-581: the runner of "softprops/action-gh-release@v1" action is too old to run on GitHub Actions. update the action's version to fix this issue

(action)

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: build-linux-packages (x86_64-unknown-linux-gnu, amd64, stt-openblas,llm-vulkan, ubuntu-24.04)
  • GitHub Check: build-appimage (x86_64-unknown-linux-gnu, x86_64, stt-openblas,llm-vulkan, ubuntu-22.04)
🔇 Additional comments (5)
.github/workflows/linux_packages.yaml (5)

1-26: Workflow configuration and environment setup look good.

Concurrency management is properly configured, and the TAURI_CONF_PATH correctly includes the apps/desktop/ prefix as documented in prior reviews. Channel-based configuration and event-based triggering are sound.


73-129: System dependency installation is well-structured.

Comprehensive base dependencies are properly configured, and ARM64 cross-compilation setup includes appropriate fallback handling for packages that may not be available in all Ubuntu repos. The cross-compilation environment variables are correctly set.


159-178: Tauri build configuration is correct.

The approach of extracting just the filename with basename is appropriate given the pnpm -F desktop context switch. All required secrets are properly wired, and verbose logging is enabled for CI transparency.


191-281: Package testing and verification logic is comprehensive and architecture-aware.

Architecture-specific test coverage distinguishes between x86_64 (where full installation and execution testing is possible) and ARM64 (where verification is limited to extraction and binary inspection on the x86_64 runner). Fallback handling for cross-compiled packages is pragmatic.


587-621: Flathub publishing scaffold is appropriately disabled and documented.

The commented-out section clearly documents prerequisites and provides a template for future enablement. The structure is sound for later implementation.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

♻️ Duplicate comments (2)
.github/workflows/linux_packages.yaml (2)

577-583: Upgrade second occurrence of deprecated softprops/action-gh-release@v1 to v2.

Line 579 also uses the deprecated softprops/action-gh-release@v1. Apply the same upgrade for consistency:

  - name: Upload AppImage to release
    if: github.event_name == 'release'
-   uses: softprops/action-gh-release@v1
+   uses: softprops/action-gh-release@v2
    with:
      files: ${{ steps.find-appimage.outputs.appimage_path }}
    env:
      GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

290-296: Upgrade deprecated softprops/action-gh-release@v1 to v2.

Line 292 uses the deprecated softprops/action-gh-release@v1, which triggers Node 16 deprecation warnings on GitHub Actions. Upgrade to v2:

  - name: Upload .deb to release
    if: github.event_name == 'release'
-   uses: softprops/action-gh-release@v1
+   uses: softprops/action-gh-release@v2
    with:
      files: ${{ steps.find-deb.outputs.deb_path }}
    env:
      GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

Apply the same upgrade to the AppImage upload step at line 579.

🧹 Nitpick comments (1)
.github/workflows/linux_packages.yaml (1)

311-315: Update deprecated runner label in commented ARM64 section.

Line 315 contains ubuntu-20.04 in the commented ARM64 build configuration. While this code is currently disabled, when ARM64 builds are re-enabled, this deprecated runner will cause failures. Update to ubuntu-24.04 now to prevent future issues:

          # ARM64 builds disabled temporarily due to cross-compilation dependency issues
          # - target: "aarch64-unknown-linux-gnu"
          #   arch: "aarch64"
          #   features: "stt-openblas,llm-vulkan"
-         #   runner: "ubuntu-20.04"
+         #   runner: "ubuntu-24.04"
📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between a5461d1 and 033b919.

📒 Files selected for processing (1)
  • .github/workflows/linux_packages.yaml (1 hunks)
🧰 Additional context used
🪛 actionlint (1.7.8)
.github/workflows/linux_packages.yaml

132-132: name is required in action metadata "/home/jailuser/git/.github/actions/setup_protoc/action.yaml"

(action)


132-132: description is required in metadata of "" action at "/home/jailuser/git/.github/actions/setup_protoc/action.yaml"

(action)


145-145: name is required in action metadata "/home/jailuser/git/.github/actions/pnpm_install/action.yaml"

(action)


145-145: description is required in metadata of "" action at "/home/jailuser/git/.github/actions/pnpm_install/action.yaml"

(action)


148-148: name is required in action metadata "/home/jailuser/git/.github/actions/poetry_install/action.yaml"

(action)


148-148: description is required in metadata of "" action at "/home/jailuser/git/.github/actions/poetry_install/action.yaml"

(action)


292-292: the runner of "softprops/action-gh-release@v1" action is too old to run on GitHub Actions. update the action's version to fix this issue

(action)


579-579: the runner of "softprops/action-gh-release@v1" action is too old to run on GitHub Actions. update the action's version to fix this issue

(action)

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: build-appimage (x86_64-unknown-linux-gnu, x86_64, stt-openblas,llm-vulkan, ubuntu-24.04)
  • GitHub Check: build-linux-packages (x86_64-unknown-linux-gnu, amd64, stt-openblas,llm-vulkan, ubuntu-24.04)

Comment on lines +131 to +148
- name: Setup Protoc
uses: ./.github/actions/setup_protoc
with:
repo-token: ${{ secrets.GITHUB_TOKEN }}

- name: Install Rust toolchain
uses: ./.github/actions/rust_install
with:
platform: "linux"

- name: Add Rust target
run: rustup target add ${{ matrix.target }}

- name: Install Node.js dependencies
uses: ./.github/actions/pnpm_install

- name: Install Python dependencies
uses: ./.github/actions/poetry_install
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

Add required metadata to three custom action files.

Static analysis confirms three custom actions are missing required name and description metadata per GitHub Actions specifications:

  • .github/actions/setup_protoc/action.yaml (line 132)
  • .github/actions/pnpm_install/action.yaml (line 145)
  • .github/actions/poetry_install/action.yaml (line 148)

Each action.yaml file must include top-level name and description fields before inputs or runs sections (e.g., name: "Setup Protocol Buffers Compiler" and description: "Sets up Protocol Buffers compiler with caching support").

Would you like me to verify that these action.yaml files exist and then generate the required metadata updates?


[/run_scripts]


🏁 Script executed:

#!/bin/bash
# Check if custom action files exist and display their content

echo "=== Checking setup_protoc action ==="
if [ -f ".github/actions/setup_protoc/action.yaml" ]; then
  echo "File exists:"
  cat ".github/actions/setup_protoc/action.yaml"
else
  echo "File not found"
fi

echo -e "\n=== Checking pnpm_install action ==="
if [ -f ".github/actions/pnpm_install/action.yaml" ]; then
  echo "File exists:"
  cat ".github/actions/pnpm_install/action.yaml"
else
  echo "File not found"
fi

echo -e "\n=== Checking poetry_install action ==="
if [ -f ".github/actions/poetry_install/action.yaml" ]; then
  echo "File exists:"
  cat ".github/actions/poetry_install/action.yaml"
else
  echo "File not found"
fi

Length of output: 1166


Add name and description metadata to three custom action files.

All three custom action files are confirmed to be missing required top-level metadata fields per GitHub Actions specifications:

  • .github/actions/setup_protoc/action.yaml – missing name and description
  • .github/actions/pnpm_install/action.yaml – missing name and description
  • .github/actions/poetry_install/action.yaml – missing name and description

Add the following fields to each action.yaml before the inputs or runs section:

  • name: "Setup Protocol Buffers Compiler" (for setup_protoc)
  • name: "Install pnpm and Node dependencies" (for pnpm_install)
  • name: "Install Python dependencies with Poetry" (for poetry_install)
  • Corresponding description: fields explaining what each action does
🧰 Tools
🪛 actionlint (1.7.8)

132-132: name is required in action metadata "/home/jailuser/git/.github/actions/setup_protoc/action.yaml"

(action)


132-132: description is required in metadata of "" action at "/home/jailuser/git/.github/actions/setup_protoc/action.yaml"

(action)


145-145: name is required in action metadata "/home/jailuser/git/.github/actions/pnpm_install/action.yaml"

(action)


145-145: description is required in metadata of "" action at "/home/jailuser/git/.github/actions/pnpm_install/action.yaml"

(action)


148-148: name is required in action metadata "/home/jailuser/git/.github/actions/poetry_install/action.yaml"

(action)


148-148: description is required in metadata of "" action at "/home/jailuser/git/.github/actions/poetry_install/action.yaml"

(action)

🤖 Prompt for AI Agents
.github/workflows/linux_packages.yaml around lines 131-148: three referenced
custom actions lack required top-level metadata in their action.yaml files; open
.github/actions/setup_protoc/action.yaml,
.github/actions/pnpm_install/action.yaml, and
.github/actions/poetry_install/action.yaml and add a top-level name and
description field (name: "Setup Protocol Buffers Compiler" and an explanatory
description for setup_protoc; name: "Install pnpm and Node dependencies" and an
explanatory description for pnpm_install; name: "Install Python dependencies
with Poetry" and an explanatory description for poetry_install) placing these
fields before the inputs or runs section so each action.yaml conforms to GitHub
Actions spec.

PythonTilk and others added 2 commits November 14, 2025 23:21
…ation

- Add foreign key constraint to contacts table with CASCADE delete
- Improve error handling in whisper-local example (remove unwrap, use expect)
- Enhance LinuxInstallNotes.md with pnpm prerequisites, xhost security warnings, and professional tone
- Fix misleading comment in audio test binary
- Correct count mismatch (two -> three systems)
fix: address CodeRabbit review findings for code quality and document…
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

♻️ Duplicate comments (2)
LinuxInstallNotes.md (1)

45-45: Fix the apt package typo.

patchel isn't a valid package name, so the install step fails. This issue was flagged in a previous review. Please update the command to use patchelf to keep the setup instructions functional.

-sudo apt install libwebkit2gtk-4.1-dev libayatana-appindicator3-dev librsvg2-dev patchel libclang-dev libxss-dev
+sudo apt install libwebkit2gtk-4.1-dev libayatana-appindicator3-dev librsvg2-dev patchelf libclang-dev libxss-dev
crates/whisper-local/examples/test_model.rs (1)

15-16: Use generic path or accept command-line argument.

The hardcoded path is specific to user "benediktb" and won't work for other developers. Consider accepting the model path as a command-line argument or using a platform-appropriate data directory.

🧹 Nitpick comments (3)
LinuxInstallNotes.md (1)

70-88: xhost usage is documented but could be clearer for typical scenarios.

The security warnings and revocation instructions are helpful, but many desktop users won't need xhost at all. Consider adding a clarification that this step is primarily for containerized or privilege-escalated scenarios, not standard local development.

You could expand the comment to:

 # access the X Window System display without authentication
-# WARNING: This relaxes X server access control for the current local user
-# Only use when running GUI apps that require X11 access (e.g., from containers/sudo)
+# WARNING: This relaxes X server access control for the current local user.
+# TYPICALLY NOT NEEDED for standard local development; only required if running GUI apps
+# from containers, sudo, or other privilege contexts that lack display access.
+# Only use when running GUI apps that require X11 access (e.g., from containers/sudo)
 # Security: Grants local user processes GUI access; avoid on multi-user systems

The PulseAudio echo cancellation, pnpm, and build commands all look correct.

crates/whisper-local/examples/test_model.rs (2)

4-13: Simplify the doc comment per coding guidelines.

This doc comment is verbose and explains "what" the function does rather than "why". Per the coding guidelines, comments should be minimal and focus on "why" not "what".

Consider simplifying to a brief one-liner:

-/// Demonstrates initializing a local Whisper model from a filesystem path and prints basic diagnostics.
-///
-/// Prints the model path, whether the file exists, the file size if available, and constructs a `Whisper` instance.
-///
-/// # Examples
-///
-/// ```no_run
-/// // Adjust the hardcoded path in the example file to point to a valid model on your system before running.
-/// crate::main();
-/// ```
+/// Example: Initialize a Whisper model from a local path.
 fn main() {

As per coding guidelines.


26-26: Remove or correct misleading comment.

The comment "Test with CPU only" is misleading since there's no CPU-specific configuration in the code. According to the AI summary, the WhisperBuilder performs GPU-first initialization with automatic CPU fallback, so this comment is inaccurate.

Apply this diff to remove the misleading comment:

-    // Test with CPU only
     let model_path_str = model_path

As per coding guidelines.

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 033b919 and ad51002.

📒 Files selected for processing (4)
  • LinuxInstallNotes.md (1 hunks)
  • crates/audio/src/bin/test_friendly_names.rs (1 hunks)
  • crates/db-user/src/contacts_migration.sql (1 hunks)
  • crates/whisper-local/examples/test_model.rs (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
  • crates/audio/src/bin/test_friendly_names.rs
  • crates/db-user/src/contacts_migration.sql
🧰 Additional context used
📓 Path-based instructions (1)
**/*.{js,ts,tsx,rs}

⚙️ CodeRabbit configuration file

**/*.{js,ts,tsx,rs}: 1. No error handling.
2. No unused imports, variables, or functions.
3. For comments, keep it minimal. It should be about "Why", not "What".

Files:

  • crates/whisper-local/examples/test_model.rs
🧬 Code graph analysis (1)
crates/whisper-local/examples/test_model.rs (1)
crates/whisper-local/src/model.rs (2)
  • model_path (26-29)
  • builder (160-162)
🔇 Additional comments (1)
LinuxInstallNotes.md (1)

1-33: Feature announcements are clear and well-structured.

The Recent Updates section effectively communicates the production-ready status of Linux support with specific, feature-focused callouts. The use of checkmarks and subsections improves readability and sets clear expectations.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants